三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 开发 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> ASP.NET -> asp.net MVC 网站图片防盗链的几种方法 -> 正文阅读
 

[ASP.NET]asp.net MVC 网站图片防盗链的几种方法

asp.net MVC 网站图片防盗链的几种方法                                 目录
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 ,同时还有自定义路由调用的 HttpHandlerImageHandler


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 最新文章
C#实战技能之WebApi+Task+WebSocket
Quartz.NET实现作业调度
从客户端(XXX)中检测到有潜在危险的Request
在已有的数据库中修改数据类型步骤
C# Email 发送邮件,对方打开通知你
在ASP.NET Core Web API中为RESTful服务增加
性能测试类,让你写法代码养成经常测试的好
ASP.NET静态页生成
“NHibernate.Cfg.Configuration 的类型初始
dataGrid多维表头,表头跨行跨列设计
上一篇文章      下一篇文章      查看所有文章
加:2017-06-12 23:32:03  更:2017-06-12 23:32:11 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2017年11日历
2017-11-20 5:48:37
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库