Home  >  Article  >  Backend Development  >  How to prevent hotlinking of images on asp.net MVC website?

How to prevent hotlinking of images on asp.net MVC website?

零下一度
零下一度Original
2017-06-23 16:07:412502browse

1.

2. Through nginx

Picture anti-hotlinking##3 .Customize HttpHandler

Processing

4. Anti-hotlinking through

MVC custom routing rules

5. Pass

Customize RouteHandler to prevent hotlinking

6. Pass

HttpModModule Anti-hotlinking

7

. Involving knowledge points and related resources

                                                                                                                                                                                                                                                                                       

Let me explain the environment first. I am using MVC4 and the IIS7 application pool is in integrated mode. The following configurations are based on this environment.

1. Through URL Rewrite Module

Component

This is a relatively simple and convenient Methods. First, go to the Url Rewite official website to download URL Rewrite Module 2.0 and install it. After the installation is completed, you can see that there are more URL rewriting modules in the IIS settings as shown below: Here, you can set the URL access rules, double-click URL Rewriting, Add inbound rules

Add {HTTP_REFERER} in condition (c) and the mode is: ^http: //localhost/.*$, which means that the request HTTP_REFERER must contain http://localhost/ characters. Of course, the rules are written according to your own situation.

After adding and saving, there will be an additional rewrite node under the system.webServer node of the site's web.config file, and the configuration is as follows.

<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>

After the configuration, does it have any effect? ​​Let’s make a test page to try

<!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>

There are 2 pictures in it. The
HTTP_REFERER
regular expression configured in IIS "Inbound Rule Conditions" is

^http://localhost/.*$

If the rule is valid, we visit http://localhost/HtmlPage1 .html pictures should be displayed normally, but if accessed through http://127.0.0.1/HtmlPage1.html, the pictures should not be displayed. The following is the effect of accessing through these two addresses.

Indicates that the configuration is successful. Of course, URL Rewrite Module is not just for image hotlink protection!

2. Through nginx

Picture anti-hotlinking

The principle of anti-hotlinking is the same. It mainly determines the source site through the referer. If the source site is not in the "white list", it will reject or return a default image

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
  如果图片是放盗链,重定向到 地址 ,一般是图片地址,但是要注意,这个图片地址不只能在此防盗链规则里,否则也访问不到。

对 nginx 配置不熟悉的同学请参考  windows 下配置 Nginx 常见问题
方法步骤: 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,满足要求的请求进入  进行处理
<span style="color: #0000ff"><</span><span style="color: #800000">system.webServer</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">handlers</span><span style="color: #0000ff">></span>  <span style="color: #0000ff"><</span><span style="color: #800000">remove </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ExtensionlessUrlHandler-Integrated-4.0"</span> <span style="color: #0000ff">/></span>  <span style="color: #0000ff"><</span><span style="color: #800000">remove </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="OPTIONSVerbHandler"</span> <span style="color: #0000ff">/></span>  <span style="color: #0000ff"><</span><span style="color: #800000">remove </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TRACEVerbHandler"</span> <span style="color: #0000ff">/></span>  
      <span style="color: #0000ff"><</span><span style="color: #800000">add </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ExtensionlessUrlHandler-Integrated-4.0"</span><span style="color: #ff0000"> path</span><span style="color: #0000ff">="*."</span><span style="color: #ff0000"> verb</span><span style="color: #0000ff">="*"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="System.Web.Handlers.TransferRequestHandler"</span><span style="color: #ff0000"> preCondition</span><span style="color: #0000ff">="integratedMode,runtimeVersionv4.0"</span> <span style="color: #0000ff">/><br>    <!-- 这是添加的自定义Handler --></span>  <span style="color: #0000ff"><</span><span style="color: #800000">add </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="<span style="color: #0000ff">jpg</span>Handler"</span><span style="color: #ff0000"> path</span><span style="color: #0000ff">="*.jpg"</span><span style="color: #ff0000"> verb</span><span style="color: #0000ff">="*"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="WeiXinDemo.Globals.MyImgHandler,WeixinDemo"</span> <span style="color: #0000ff">/><br>    <span style="color: #0000ff"><<span style="color: #800000">add <span style="color: #ff0000">name<span style="color: #0000ff">="<span style="color: #0000ff">png</span>Handler"<span style="color: #ff0000"> path<span style="color: #0000ff">="*.png<span style="color: #0000ff">"<span style="color: #ff0000"> verb<span style="color: #0000ff">="*"<span style="color: #ff0000"> type<span style="color: #0000ff">="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" <span style="color: #0000ff">/><br></span></span><<span style="color: #800000">add <span style="color: #ff0000">name<span style="color: #0000ff">="<span style="color: #0000ff"><span style="color: #800000"><span style="color: #ff0000"><span style="color: #0000ff"><span style="color: #ff0000"><span style="color: #0000ff">bmp</span></span></span></span></span></span>Handler"<span style="color: #ff0000"> path<span style="color: #0000ff">="**.bmp<span style="color: #0000ff">"<span style="color: #ff0000"> verb<span style="color: #0000ff">="*"<span style="color: #ff0000"> type<span style="color: #0000ff">="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" <span style="color: #0000ff">/><br><<span style="color: #800000">add <span style="color: #ff0000">name<span style="color: #0000ff">="<span style="color: #0000ff"><span style="color: #800000"><span style="color: #ff0000"><span style="color: #0000ff"><span style="color: #ff0000"><span style="color: #0000ff"><span style="color: #0000ff">gif</span></span></span></span></span></span></span>Handler"<span style="color: #ff0000"> path<span style="color: #0000ff">="<span style="color: #0000ff">*.gif"<span style="color: #ff0000"> verb<span style="color: #0000ff">="*"<span style="color: #ff0000"> type<span style="color: #0000ff">="WeiXinDemo.Globals.MyImgHandler,WeixinDemo" <span style="color: #0000ff">/><span style="color: #0000ff"></</span><span style="color: #800000">handlers</span><span style="color: #0000ff">></span>      
  <span style="color: #0000ff"></</span><span style="color: #800000">system.webServer</span><span style="color: #0000ff">></span>

<br><strong><span style="font-size: 18px; color: #0000ff"> 4. 通过 </span></strong><strong><span style="font-size: 18px; color: #0000ff">MVC 自定义路由规则防盗链<br></span></strong>    <span style="font-size: 14px"><br>    首先我们要在 web.config 文件里 <span style="color: #800000">system.webServer</span> 节点下 设置<span style="color: #0000ff"><<span style="color: #993300">modules <span style="color: #ff0000">runAllManagedModulesForAllRequests<span style="color: #0000ff">="true" <span style="color: #0000ff">/>  <span style="color: #000000">同时还要在 <span style="color: #ff6600">RouteConfig.cs</span> 文件里添加 routes.RouteExistingFiles = true;确保所有路由都通过 RouteCollection 匹配 。<br></span></span></span><span style="font-size: 14px">在这里我们需要了解 UrlRoutingModule,它是System.Web.Routing的一部分。UrlRoutingModule用于检验请求的url和本地硬盘 中的文件能不能相匹配。</span>如果匹配,则交给IIS处理。如果不匹配它会检验 RouteCollection 来决定能不能继续传递请求。而设置了 <span style="font-size: 14px"><span style="color: #0000ff"><span style="color: #993300"><span style="color: #ff0000">runAllManagedModulesForAllRequests<span style="color: #0000ff">="true"</span></span></span></span></span> 后,会改变默认行为,所有请求都须要 运用 Routing来处理。<br>
<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>
After setting the configuration file, add custom routing rules. The following are custom routing rules The implementation code actually does one thing, using regular expressions to determine whether the current request complies with the rules. If it complies with the rules, it will enter the specified processing page, otherwise it will match other routing rules.
<br>
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;
        }
    }
}
<br>

    这样就造成了一个问题,所有的请求(比如 .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: ImgRulepublic 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;
        }
    }
<br>5. 通过 MVC 自定义 RouteHandler 防盗链
1  文件配置同,也要开启 
2 创建自定义路由,自定义路实现代码如下  ,同时还有自定义路由调用的  ,
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 }
            );
            
        }
    }
}
<br>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

     +=  BeginRequest(= regex =  Regex( request = (!regex.IsMatch(request.RawUrl))  (request.UrlReferrer ==  || ! 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. 涉及知识<br>

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

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种 次之。 条条大路通罗马,就看那种方法最适合。

     

The above is the detailed content of How to prevent hotlinking of images on asp.net MVC website?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn