asp.net MVC 网站图片防盗链的几种方法
目录
自己网站上的图片被别的网站盗用是一件很令人厌恶的事情,下面是处理图片盗链的几种方法。
在这里先交代一下环境,我用的是 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 组件的使用
Creating Rewrite Rules for the URL Rewrite Module
2. Nginx
3. IIS 工作原理,asp.net 管线
ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)
4. Mvc UrlRouting 处理机制
本文只是在这里探讨了一下实现防盗链的方法,没有考虑性能的问题,如果考虑性能跟简便性,我个人喜欢用 第 1 和第 2种实现方式,第 3种 次之。 条条大路通罗马,就看那种方法最适合。
asp.net MVC 网站图片防盗链的几种方法的更多相关文章
- 关于linux asp.net MVC网站中 httpHandlers配置无效的处理方法
近期有Jexus用户反映,在Linux ASP.NET MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404( ...
- nginx安全:配置网站图片防盗链
一,为什么要做防盗链? 1,什么是盗链? 比如某人有一个A网站, 他不愿自己存储图片,(因为磁盘和带宽都有成本) 就在自己A网站的页面上直接插入B网站的图片, 从而为自己吸引流量,这就是盗链 2,为什 ...
- Nginx防盗链的3种方法 文件防盗链 图片防盗链 视频防盗链 linux防盗链
Nginx 是一个很牛的高性能Web和反向代理服务器, 它具有有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品,目前Web服务器调查显示Apache下降Ngni ...
- Nginx防盗链的3种方法
一:一般的防盗链如下: location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked www.jzxue.com jzxue.c ...
- ASP.NET MVC 控制器向View传值的三种方法
转自:http://www.cnblogs.com/shinima/p/3940452.html 1.提供视图模型对象 你能把一个对象作为View方法的参数传递给视图. public ViewResu ...
- ASP.NET 实现简单的图片防盗链介绍
在此,网站图片防盗链的方法是,通过获取Http请求头中的 Referer 标头与本网站域名比较,来判断用户是否来自本站跳转过来的 . 创建一个全局处理程序,用来处理images目录下的图片的直接请求: ...
- Nginx中防盗链(下载防盗链和图片防盗链)操作记录
日常运维工作中,设置防盗链的需求会经常碰到,这也是优化网站的一个必要措施.今天在此介绍Nginx中设置下载防盗链和图片防盗链的操作~ 一.Nginx中下载防盗链的操作记录对于一些站点上的下载操作,有很 ...
- Nginx中防盗链(下载防盗链和图片防盗链)及图片访问地址操作记录
日常运维工作中,设置防盗链的需求会经常碰到,这也是优化网站的一个必要措施.今天在此介绍Nginx中设置下载防盗链和图片防盗链的操作~ 一.Nginx中下载防盗链的操作记录对于一些站点上的下载操作,有很 ...
- ASP.NET MVC 网站开发总结(三) ——图片截图上传
本着简洁直接,我们就直奔主题吧,这里需要使用到一个网页在线截图插件imgareaselect(请自行下载). 前台页面: <!DOCTYPE html> <html> < ...
随机推荐
- 【原】Unity Shader VS UDK Material Editor
UDK 的材质编辑器十分好用,毕竟是所见即所得的.虽然unity也有类似第三方插件,但易用性还是差很多,下面主要是,把一些常见表达式概念对应起来. 1. UDK CameraVector (相机位向量 ...
- hibernate 多对多关系总结
hibernate中,对对象关系的映射处理估计是最让人迷惑和头疼的,特别是cascade和inverse属性的使用,不知已经杀死了我多少个脑细胞了,好记性永远比不上烂笔头,为了能节省自己的脑细胞,降低 ...
- 55 Jump Game i && 45 Jump Game ii
Jump Game Problem statement: Given an array of non-negative integers, you are initially positioned a ...
- 利用Python进行简单的图像识别(验证码)
这是一个最简单的图像识别,将图片加载后直接利用Python的一个识别引擎进行识别 将图片中的数字通过 pytesseract.image_to_string(image)识别后将结果存入到本地的txt ...
- (5)微信二次开发 之 XML格式数据解析
1.首先理解一下html html的全名是:HyperText Transfer markup language 超级文本标记语言,html本质上是一门标记(符合)语言,在html里,这些标记是事先定 ...
- 1.centOS安装Mysql
上个星期研究了一个星期的Mysql,从今天起把学到的东西整理一下. ---------------------------------------------- mysql安装本人亲试过两种安装方式, ...
- 设计模式浅谈----策略模式(c#及java实现)
一.何为策略模式 策略模式是行为型模式的一种,主要用于需要使用不同的算法来处理不同的数据对象时使用,是一种可以在运行时选择算法的设计模式.也称为政策模式. 主要解决:在有多种算法相似的情况下,使用 i ...
- Java字符串连接最佳实践
一个小问题,分享给大家. + 操作和 StringBuilder 都能连接字符串,使用+来拼接字符串,使用javap命令来反编译代码,可以看出实际上编译器会自动创建StringBuilder,调用它的 ...
- js算法集合(二) javascript实现斐波那契数列 (兔子数列)
js算法集合(二) 斐波那契数列 ★ 上一次我跟大家分享一下做水仙花数的算法的思路,并对其扩展到自幂数的算法,这次,我们来对斐波那契数列进行研究,来加深对循环的理解. Javascript实 ...
- Tomcat8-源码编译及开发
前言 下载Tomcat8源码进行分析,最好的方式,可以编译及运行,从网上查询了很多方式,总是不能完整的运行,由于本人采用idea编辑器,所以喜欢maven的方式,所以综合了网上的多种方案,最终可以在i ...