转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链
【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链
你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽。下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义RouteHandler来防止其他人盗链你的图片.
首先,我们来回顾一下当一个请求发往ASP.net MVC站点时的情景,IIS收到请求并将请求转到ASP.net,然后根据URL,或者更确切来说:被请求文件的扩展名.在IIS7 integrated模式下(默认模式),所有的请求都会匹配到ASP.net中,而在IIS6中,你可以通过通配符来达到和IIS7相同的效果.
在ASP.NET MVC程序中首先涉及的部件是UrlRoutingModule,它是System.Web.Routing的一部分.UrlRoutingModule用于第一次检查请求的url和本地磁盘中的文件是否相匹配。如果匹配,UrlRoutingModule会将请求直接回发给IIS,IIS根据地址来进行相应。如果UrlRoutingModule没有在磁盘中找到匹配的文件。它会检查RouteCollection结构来决定是否继续传递请求.UrlRoutingModule会引入RouteHandler和匹配的路径入口(默认情况下是MvcRouteHandler)。而后会引入合适的HttpHandler来处理和请求有关的逻辑。默认情况下,这个HttpHandler会是MvcHandler.而对于图片文件,一般会存在于程序中的某个子目录中,核心的routeModule并没有这种能力因为直接索取图片的url回优先回发给iis,而流程在这时无法执行到RouteHandler被引入.
通常情况下,通过Asp.net取出磁盘上的静态文件都是可以的。然而,如果你想执行一些业务逻辑而不是直接让这类文件响应请求。你需要在某些关键点以编程的方式实现。你可以通过设置RouteTable.Routes.RouteExistingFiles = true来避免对现有文件的默认相应行为。Phil Haack( ASP.NET MVC的高级程序经理)称之为”核武器级别的选项”,无论是css,js,doc,pdf等文件,在这种模式下所有文件都需要利用Routing来处理。所以确保这一点的关键是对于静态文件的请求不能和磁盘上对应的文件匹配。这会强制RouteModule来对Route表(当然会引入RouteHandler等过程)进行查找。这很容易做,只需要让<img>元素指向一个虚构的目录即可。比如说,你的图片是存放在网站根目录下的images文件夹下,而<img>元素指向一个”graphics”文件夹将不会和存在的文件相匹配。
想做到这些,需要做如下:
- 为对于图片的请求注册Route
- 创建RouteHandler来处理这类请求
- 创建HttpHandler来处理实际的请求
我们首先从步骤2开始,因为如果没有创建RouteHandler却要在路由表中进行注册的话,这不会编译成功的.
RouteHandler很简单,它是IRouteHandler的实现,它只有一个方法--IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext):
public class ImageRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new ImageHandler(requestContext);
}
}
对于实际的HttpHandler:
public class ImageHandler : IHttpHandler
{
public ImageHandler(RequestContext context)
{
ProcessRequest(context);
} private static void ProcessRequest(RequestContext requestContext)
{
var response = requestContext.HttpContext.Response;
var request = requestContext.HttpContext.Request;
var server = requestContext.HttpContext.Server;
var validRequestFile = requestContext.RouteData.Values["filename"].ToString();
const string invalidRequestFile = "thief.gif";
var path = server.MapPath("~/graphics/"); response.Clear();
response.ContentType = GetContentType(request.Url.ToString()); if (request.ServerVariables["HTTP_REFERER"] != null &&
request.ServerVariables["HTTP_REFERER"].Contains("mikesdotnetting.com"))
{
response.TransmitFile(path + validRequestFile);
}
else
{
response.TransmitFile(path + invalidRequestFile);
}
response.End();
} 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;
} public void ProcessRequest(HttpContext context)
{
} public bool IsReusable
{
get { return false; }
}
}
在上面代码中,IHttpHandler中的ProcessRequest,有两个重载,第一个是public void ProcessRequest(HttpContext context),在这里我们忽略这个重载,在MVC程序中,我们传入RequestContext对象作为参数,而不是HttpContext对象。ProcessRequest方法会在ImageHandler的构造器中进行调用,在上面代码中,ProcessRequest会首先检查请求图片的地址是否输入我的域(也就是引用图片的网页是我的网站而不是其它人的),如果不是的话,则返回一张其它图片。返回什么样的图片取决于你自己,我看到过很多种这样的图片,有些包含不和谐内容.甚至你可以返回一个1px的透明gif,或者可以使404 not found….
当然,在这点上你还可以采取一些其它步骤,比如说,你当然会希望google索引你的图片,所以如果引用的链接包含”images.google”你可以返回真实图片。你也可以在其它网站盗链你图片不成功的情况下来用日志进行记录.
最后一步要做的是为对图片的请求注册到RouteTable,用于表示ImageRouteHandler来对这部分请求进行处理,在global.axax文件中,加入:
routes.Add("ImagesRoute",
new Route("images/{filename}", new ImageRouteHandler()));
希望这篇文章不仅可以帮助你阻止那些盗链的吸血鬼,还能让你对Asp.net MVC的底层有更深入的了解以便于你以后再有其他需求时可以进行扩展。
-----------------------------------------------------------------------------
http://www.cnblogs.com/CareySon/archive/2009/12/30/1636438.html
translated by:Careyson
补充:我的是MVC5,IIS7,还需要加上web.config
<modules runAllManagedModulesForAllRequests="true" >才行。
转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链的更多相关文章
- Asp.net MVC 利用自定义RouteHandler来防止图片盗链
你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...
- [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证
很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...
- ASP.NET MVC 利用IRouteHandler, IHttpHandler实现图片防盗链
你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...
- [译]Asp.net MVC 之 Contorllers(二)
URL路由模块 取代URL重写 路由请求 URL路由模块的内部结构 应用程序路由 URL模式和路由 定义应用程序路由 处理路由 路由处理程序 处理物理文件请求 防止路由定义的URL 属性路由 书接上回 ...
- [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
原文:[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面 随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就 ...
- ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender
(原文) 昨天在ASP.NET MVC利用PagedList分页(一)的 最后一节提到,一个好的用户体验绝对不可能是点击下一页后刷新页面,所以今天来说说利用Ajax+PagedList实现无刷新(个人 ...
- 【转】Asp.net MVC 通过自定义ControllerFactory实现构造器注入(重写DefaultControllerFactory)
[转]Asp.net MVC 通过自定义ControllerFactory实现构造器注入 一.重写ControllerFactory的GetControllerInstance ControllerF ...
- 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)
一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- [转]Asp.net MVC 利用PartialView 构造自定义菜单
本文转自:http://www.cnblogs.com/huyq2002/archive/2012/01/06/2314838.html 在VS2010中利用Asp.net MVC自带的模板生成的菜单 ...
随机推荐
- java正则表达式验证标点符号
统计标点符号个数 String str = "\""..,!,"; int count = 0; Pattern pattern = Pattern.compi ...
- 利用微信公众平台实现自动回复消息—java版
最近公司需要拿微信公众平台做个东西,所以就开始了最基本学习,网上很多是php版的,对于我这个只会java,不会php的就只能在网上找点只言片语来一点一点学习了.不费话了直接贴图看效果(很简单的). 不 ...
- DNS:域名系统
DNS:域名系统 1.DNS DNS 是计算机域名系统(Domain Name System 或Domain Name Service) 的缩写,它是由解析器以及域名服务器组成的.域名服务器 ...
- 一步一步深入spring(7)-- 整合spring和JDBC的环境
1.配置数据源 (1).添加支持数据源的jar包commons-dbcp.jar .commons-pool.jar 当然也要添加其他的spring用到的jar以及这里用到的数据库mysql的jar ...
- C# 与 C++强强联合--C#中的指针
C# 与 C++强强联合--C#中的指针 非常的不好意思,距离上次随笔C# 与 C++强强联合已经过去快1个月了.承诺大家的C#指针和A*算法迟迟未上.为表歉意献上美女一枚 哈哈.流口水了吧 话归正题 ...
- J2EE (九) 静态代理和动态代理--间接“美”
生活中有很多例子是间接来控制和访问的,比如你找一个人不自己亲自去,而是让别人代替去做这就是最简单的代理模式,是一种间接通信的例子,对象间的间接通信也同样是面向对象设计中的一条重要的“审美观”.间接通信 ...
- Run SPLAHS2 under SE mode on gem5在gem5的SE模式下,运行SPLASH2程序
1. 安装相关的gem5,可以参考以前的博客. 2. 下载splash2编译好的软件 首先从gem5的官网下载已经编译成alpha指令集的splash2.下载地址:http://www.gem5. ...
- PHP自学之路---雇员管理系统(2)
这个章节将讲解分层模式对雇员管理系统的系统,首先看下基本的流程图设计: 下面是具体的代码: 1.login.php(参照上节) 2.loginProcess.php <?php /** * * ...
- Dockerfile与Docker构建流程解读
摘要 本文主要讨论了对docker build的源码流程进行了梳理和解读,并分享了在制作Dockerfile过程中的一些实践经验,包括如何调试.优化和build中的一些要点.另外,还针对现有Docke ...
- JVM执行引擎的执行过程
摘自深入分析java web技术内幕