目录

1. 通过 URL Rewrite Module 组件

2. 通过 nginx 图片防盗链

3.自定义 HttpHandler 处理

4. 通过 MVC 自定义路由规则防盗链

5. 通过 MVC 自定义 RouteHandler 防盗链

6. 通过 HttpModModule 防盗链

7. 涉及知识点,相关资源

自己网站上的图片被别的网站盗用是一件很令人厌恶的事情,下面是处理图片盗链的几种方法。

在这里先交代一下环境,我用的是 MVC4 ,IIS7 应用程序池为集成模式,以下配置都是基于此环境进行。

1. 通过 URL Rewrite Module 组件

这是一个比较简单,方便的方法。首先要去 Url Rewite 官网 下载 URL Rewrite Module 2.0 并安装。安装完成后可以看到 IIS设置里多了  URL重写 的模块如下图:

在这里,可以对URL访问规则进行设置, 双击 URL 重写,添加入站规则

在条件(c)  里面添加  {HTTP_REFERER}    模式为: ^http://localhost/.*$, 意思是 请求  HTTP_REFERER 必须包含 http://localhost/ 字符,规则当然是根据自己的情况写。

添加保存后,站点的 web.config 文件的 system.webServer 节点下就多了 rewrite 节点,配置如下。

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<rewrite>
<rules>
<rule name="防盗链" stopProcessing="true">
<match url=".*\.(gif|jpg|png)" />
<conditions>
<add input="{HTTP_REFERER}" pattern="^http://localhost/.*$" negate="true" />
</conditions> <action type="Redirect" url="http://www.baidu.com" />
</rule>
</rules>
</rewrite>
</system.webServer>

配置好了,有没有效果呢,我们做一个测试页面试试

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<img src="Content/webpage/img/111.jpg" />
<img src="111.jpg"/>
</body>
</html>

里面有2张图片,由于在IIS “入站规则条件” 里面配置的  HTTP_REFERER  正则表达式为 ^http://localhost/.*$  如果规则有效,我们访问 http://localhost/HtmlPage1.html  图片应正常显示,而如果通过  http://127.0.0.1/HtmlPage1.html  访问是不应该显示图片的,下面是我通过这两个地址访问效果。

   

说明配置是成功的。当然了,URL Rewrite Module 并非仅仅做图片防盗链哟!

2. 通过 nginx 图片防盗链

防盗链的原理都是一样的,主要是通过 referer 判断来源站点,如果来源站点不在 “白名单” 里,则拒绝或返回一张默认图片

location ~.*\.(jpg|gif|png)$ {
valid_referers none blocked *.abc.com abc.com;
if ($invalid_referer) {
#rewrite ^/ http://abc.com/error.html;
return 403;
}
}
location ~.*\.(jpg|gif|png)$  表示所有 以 jpg|gif|png 为后缀名的文件都进行防盗链处理
valid_referers none blocked *.abc.com abc.com;   验证 referer  其中 none 表示直接访问的,不存在referer   blocked为根据防火墙伪装的 referer 
#rewrite ^/ http://abc.com/error.html;  如果图片是放盗链,重定向到 地址 http://abc.com/error.html,一般是图片地址,但是要注意,这个图片地址不只能在此防盗链规则里,否则也访问不到。

对 nginx 配置不熟悉的同学请参考  windows 下配置 Nginx 常见问题

3.自定义 HttpHandler
处理 方法步骤: 1 创建自定义 handlers 代码如下,根据 Referre 判断请求来源,如果符合标准,输出文件流,否则停止响应。也可以输出一个特定的图片。
namespace WeiXinDemo.Globals
{
/// <summary>
/// 测试 Handler 实现图片防盗链
/// </summary>
public class MyImgHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
} public void ProcessRequest(HttpContext context)
{
var response = context.Response;
var request = context.Request; if (request.UrlReferrer == null || !WebApplication.ImgHost.Equals(request.UrlReferrer.Host))
{
response.End();
return;
} var fileName = context.Server.MapPath(request.FilePath);
response.WriteFile(fileName); if (request.UrlReferrer == null || WebApplication.ImgHost.Equals(request.UrlReferrer.Host))
{
response.WriteFile(fileName);
}
else
{
response.End();
}
}
}
}

2 在web.config 文件 handlers 节点下添加自定义 Handler,满足要求的请求进入 WeiXinDemo.Globals.MyImgHandler 进行处理
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    <!-- 这是添加的自定义Handler -->
<add name="jpgHandler" path="*.jpg" verb="*" type="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" />
    <add name="pngHandler" path="*.png" verb="*" type="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" />
<add name="bmpHandler" path="**.bmp" verb="*" type="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" />
<add name="gifHandler" path="*.gif" verb="*" type="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" />
</handlers>
</system.webServer>
 4. 通过 MVC 自定义路由规则防盗链

首先我们要在 web.config 文件里 system.webServer 节点下 设置<modules runAllManagedModulesForAllRequests="true" /> 同时还要在 RouteConfig.cs 文件里添加 routes.RouteExistingFiles = true;确保所有路由都通过 RouteCollection 匹配 。
在这里我们需要了解 UrlRoutingModule,它是System.Web.Routing的一部分。UrlRoutingModule用于检验请求的url和本地硬盘 中的文件能不能相匹配。如果匹配,则交给IIS处理。如果不匹配它会检验 RouteCollection 来决定能不能继续传递请求。而设置了 runAllManagedModulesForAllRequests="true" 后,会改变默认行为,所有请求都须要 运用 Routing来处理。
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>

配置文件设置好以后添加自定义路由规则,下面是自定义路由规则的实现代码,其实里面就做了一件事,使用正则表达式判断当前请求是否符合规则,如果符合规则,则进入指定的处理页面,否则去匹配其他的路由规则。


namespace WeiXinDemo.Globals
{
/// <summary>
/// 图片路由规则(自定义)
/// </summary>
public class ImgRouteRule : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var regex = new Regex(@"/[^/]+(.jpg|.bmp|.gif|.png)");
var result = regex.IsMatch(httpContext.Request.RawUrl);
return result;
}
}
}

这样就造成了一个问题,所有的请求(比如 .css  .js  .htm 等等)都去路由规则里面去匹配,如果在路由规则里面匹配不到那么就会返回 404,如何避免呢?通过 RouteConfig.cs 文件配置忽略。

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//确保所有路由都通过 RouteCollection 匹配(图片防盗链)
routes.RouteExistingFiles = true; //忽略 json,html,js,css文件
routes.IgnoreRoute("{*pathInfo}", new { pathInfo = @".+(.json|.html|.js|.css)" });
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//符合路由规则的转到控制器 ImgRule/Index 处理 (自定义路由规则实现 图片防盗链)
routes.MapRoute(
name: "ImagesRoute",
url: "{*catchall}",
defaults: new { controller = "ImgRule", action = "Index" },
// ImgRouteRule 为自定义路由规则,符合此规则,进入路由 访问 ImgRule/Index
constraints: new { customConstraint = new ImgRouteRule() },
//控制器类命名空间
namespaces: new[] { "WeiXinDemo.Controllers" }); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

在上面的代码里配置了 "ImagesRoute"   的路由,使用的自定义路由规则,当满足规则时,跳转到 ImgRule/Index 去处理,处理代码跟使用 HttpHandler 类似

 public class ImgRuleController : Controller
{
// GET: ImgRule
public FileStreamResult Index()
{
var fPath = Server.MapPath("~" + Request.FilePath);
if (Request.UrlReferrer == null) return null; if (!System.IO.File.Exists(fPath) || !WebApplication.ImgHost.Equals(Request.UrlReferrer.Host) || !WebApplication.ImgHost.Equals(Request.UrlReferrer.Host))
return null;
return GetFile(fPath);
} private FileStreamResult GetFile(string fPath)
{
return File(new FileStream(fPath, FileMode.Open, FileAccess.Read), GetContentType(Request.FilePath));
} private static string GetContentType(string url)
{
switch (Path.GetExtension(url))
{
case ".gif":
return "Image/gif";
case ".jpg":
return "Image/jpeg";
case ".png":
return "Image/png";
default:
break;
}
return null;
}
}

5. 通过
MVC 自定义 RouteHandler 防盗链
注意这里是自定义路由,别跟第4种方法混淆了,这里是指定自定义路由处理图片。
1 web.config 文件配置同第4种方法,也要开启 runAllManagedModulesForAllRequests="true"
2 创建自定义路由,自定义路实现代码如下 ImageRouteHandler ,同时还有自定义路由调用的 HttpHandler ,ImageHandler
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Routing; namespace WeiXinDemo.Globals
{
/// <summary>
/// 测试自定义 RouteHandler 图片防盗链
/// </summary>
public class ImageRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new ImageHandler();
}
} /// <summary>
/// 自定义路由调用的 HttpHandler
/// </summary>
public class ImageHandler : IHttpHandler
{
public ImageHandler()
{ } public bool IsReusable
{
get
{
return true;
}
} public void ProcessRequest(HttpContext context)
{
var response = context.Response;
var request = context.Request; if (request.UrlReferrer == null || !WebApplication.ImgHost.Equals(request.UrlReferrer.Host))
{
response.End();
return;
} var fileName = context.Server.MapPath(request.FilePath);
response.WriteFile(fileName);
}
}
}

RouteConfig.cs 文件配置 如下,这里指定了 对根目录下的 jpg 文件的访问进入指定路由处理程序 ImageRouteHandler。    其实这里可以把图片都放在某一个特定文件夹下,然后对这个文件夹下文件的访问做放盗链。

namespace WeiXinDemo
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//确保所有路由都通过 RouteCollection 匹配(图片防盗链)
routes.RouteExistingFiles = true; //忽略 json,html,js,css文件
routes.IgnoreRoute("{*pathInfo}", new { pathInfo = @".+(.json|.html|.js|.css)" });
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //图片防盗链
routes.Add("ImagesRoute",
new Route("{name}.jpg", new ImageRouteHandler())); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
); }
}
}

6. 通过
HttpModule 防盗链
1. 修改 web.config 配置文件  
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" >
<add name="ImgModule" type="WeiXinDemo.Globals.ImageModel,WeiXinDemo"/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
</handlers>
</system.webServer>

2. 创建实现 IHttpModule 接口的 ImageModel 类

using System;
using System.Text.RegularExpressions;
using System.Web; namespace WeiXinDemo.Globals
{
/// <summary>
/// 测试 HttpModel 图片防盗链
/// </summary>
public class ImageModel : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequest);
} void BeginRequest(object sender, EventArgs e)
{
HttpApplication context = (HttpApplication)sender; var regex = new Regex(@"/[^/]+(.jpg|.bmp|.gif|.png)");
var request = context.Context.Request;
if (!regex.IsMatch(request.RawUrl)) return; if (request.UrlReferrer == null || !WebApplication.ImgHost.Equals(request.UrlReferrer.Host))
{
context.Context.Response.End();
return;
} var fileName = context.Context.Server.MapPath(request.FilePath);
context.Context.Response.WriteFile(fileName);
}
}
}

3.  RouteConfig.cs 文件忽略不需要防盗链的静态资源

using System.Web.Mvc;
using System.Web.Routing; namespace WeiXinDemo
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//确保所有路由都通过 RouteCollection 匹配(图片防盗链)
routes.RouteExistingFiles = true; //忽略 json,html,js,css文件
routes.IgnoreRoute("{*pathInfo}", new { pathInfo = @".+(.json|.html|.js|.css)" });
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
7. 涉及知识

本文只做了一件事情,图片防盗链,其实从不同的实现方式来看它涉及到不同的知识。

1. URL Rewrite Module  组件的使用

如何使用mod_rewrite模块完成URL重写

Creating Rewrite Rules for the URL Rewrite Module

2.  Nginx

借助Nginx搭建反向代理服务器

使用nginx实施负载均衡

3. IIS 工作原理,asp.net 管线

IIS是如何处理ASP.NET请求的

ASP.NET那点不为人知的事

IIS 内部运行机制

ASP.NET MVC5请求管道和生命周期

ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)

4. Mvc UrlRouting 处理机制

MVC之前的那点事儿系列(8):UrlRouting的理解

本文只是在这里探讨了一下实现防盗链的方法,没有考虑性能的问题,如果考虑性能跟简便性,我个人喜欢用 第 1 和第 2种实现方式,第 3种 次之。 条条大路通罗马,就看那种方法最适合。

asp.net MVC 网站图片防盗链的几种方法的更多相关文章

  1. 关于linux asp.net MVC网站中 httpHandlers配置无效的处理方法

    近期有Jexus用户反映,在Linux ASP.NET MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404( ...

  2. nginx安全:配置网站图片防盗链

    一,为什么要做防盗链? 1,什么是盗链? 比如某人有一个A网站, 他不愿自己存储图片,(因为磁盘和带宽都有成本) 就在自己A网站的页面上直接插入B网站的图片, 从而为自己吸引流量,这就是盗链 2,为什 ...

  3. Nginx防盗链的3种方法 文件防盗链 图片防盗链 视频防盗链 linux防盗链

    Nginx 是一个很牛的高性能Web和反向代理服务器, 它具有有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品,目前Web服务器调查显示Apache下降Ngni ...

  4. Nginx防盗链的3种方法

    一:一般的防盗链如下: location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked www.jzxue.com jzxue.c ...

  5. ASP.NET MVC 控制器向View传值的三种方法

    转自:http://www.cnblogs.com/shinima/p/3940452.html 1.提供视图模型对象 你能把一个对象作为View方法的参数传递给视图. public ViewResu ...

  6. ASP.NET 实现简单的图片防盗链介绍

    在此,网站图片防盗链的方法是,通过获取Http请求头中的 Referer 标头与本网站域名比较,来判断用户是否来自本站跳转过来的 . 创建一个全局处理程序,用来处理images目录下的图片的直接请求: ...

  7. Nginx中防盗链(下载防盗链和图片防盗链)操作记录

    日常运维工作中,设置防盗链的需求会经常碰到,这也是优化网站的一个必要措施.今天在此介绍Nginx中设置下载防盗链和图片防盗链的操作~ 一.Nginx中下载防盗链的操作记录对于一些站点上的下载操作,有很 ...

  8. Nginx中防盗链(下载防盗链和图片防盗链)及图片访问地址操作记录

    日常运维工作中,设置防盗链的需求会经常碰到,这也是优化网站的一个必要措施.今天在此介绍Nginx中设置下载防盗链和图片防盗链的操作~ 一.Nginx中下载防盗链的操作记录对于一些站点上的下载操作,有很 ...

  9. ASP.NET MVC 网站开发总结(三) ——图片截图上传

    本着简洁直接,我们就直奔主题吧,这里需要使用到一个网页在线截图插件imgareaselect(请自行下载). 前台页面: <!DOCTYPE html> <html> < ...

随机推荐

  1. 深入理解MVC

    首先我们来看看MVC架构的示意图:             和访问者交互的是控制层(Controller层),控制器(controller)是同类交互的集合,每一个交互的操作,都对应了一个动作(act ...

  2. [Linux] PHP程序员玩转Linux系列-升级PHP到PHP7

    1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...

  3. Unity 相机的聚焦功能

    摘要:本文原创,转载请注明出处 需求: 在游戏的任务编辑场景进行编辑的时候,摄像机需要在多个需要编辑的物体之间来回切换,如果只是用摄像机的移动旋转,对于相对位置较近的物体还好说,当相对位置过远的时候, ...

  4. 速成制作rpm包

    FPM 由于很多软件在安装时需要编译,这会浪费不少的时间,为了提升部署效率,于是就想到制作rpm包.通常rpm包的制作是使用rpmbuild命令来制作,但是你需要知道它的语法,比较繁琐.这就用到了FP ...

  5. 一款Modbus设备调试工具Winform(包括SRC0001、海康威视、TTS以及各种类型LED的测试)

    1.SRC寄存器读写测试 2.采集数据终端模块(这里是康海时代)调试 3.RS485传感器设备调试 4.LED/TTS/海康威视等展示设备调试 5.Modbus等协议规约资料及4-20mA设备调试 以 ...

  6. 安装node-saas包报错问题

    项目中用到一些sass写的样式,但是每次一编译就报错 按照它上面的提醒,npm rebuild node-sass --force,还是一样有错.不过仔细看看他的错误信息我发现了其中这条: gyp v ...

  7. file_get_contents url

    file_get_contents (PHP 4 >= 4.3.0, PHP 5) file_get_contents — 将整个文件读入一个字符串 说明¶ string file_get_co ...

  8. 蓝桥杯-组素数-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  9. Idea+maven+tomcat部署第一个tomcat项目

    IDEA创建Maven项目及部署发布,IDEA配置Tomcat,创建java源文件夹. 此教程适合刚刚使用IDEA的新手. 工具/原料   IntelliJ IDEA 2016.3.4 apache- ...

  10. JavaScript中return的用法和this的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对this和函数中的return的用法和意思理解的比较模糊,这里写一篇博客跟大家一起探讨一下return和this的 ...