HttpHandler实现媒体文件和图像文件的盗链(防盗链设计)

IIS7有集成模式与经典模式两种,经典模式与IIS6进行了很好的兼容,在发布站点后,使用经典模式时,IIS会读取网站自己的web.config,而集成模式是走IIS自己提供的默认的web.config.

我们今天对图像服务器进行一个设计,使我们网站的图像成功进行防盗链,即从别的网站无法访问和下载我们网站的图像,呵呵。

注意的问题:

在IIS7里进行handler设置时,只能对一次对一种文件进行约束,不能用逗号把多个扩展名分开,表看下面图中,虽然“示例”是用逗号分开的,但实际中根据无法实现,在这里朋友们请注意一下!

好了,我们现在我抢建图像服务器吧。

第一:建立站点:

没什么好说的,向以往建立WEB站点的方式就可以了,主要是给图像一个HTTP的服务

第二 添加处理程序映射,注意,我们由于使用的是集成模式,所以需要在IIS7里进行手动设置,因为是图像服务器,所以也不存在在程序里你的web.config,使用集合模式后,当你第一次运行网站,它在根目录下自动会生成的。

请求路径指我们为文件扩展名进行设置,如*.png,这里只能出现一个扩展名,图中“示例”是错误的,类型指的是你类的全名(包括命名空间),名称是显示的名字。

第三 将你的DLL程序集放在根目录的bin目录下,注意必须放在bin目录,当然你的图像站点肯定没有bin,这时你需要手动建立一个。

第四 运行你的图像服务器,如果是从其它网站请求过来的,就会显示默认的防盗链图像了

有时,还是感觉IIS6更好用,简单的总是最好的!呵呵!

 

 

 

小知识:

一个WEB的请求从客户端发到到服务端接收,处理并返回给客户端,它的流程是这样的(以aspx页面为例):

   HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

       inetinfo.exe进程:是www服务的进程,IIS服务和ASPNET_ISAPI.DLL都寄存在此进程中。

  ASPNET_ISAPI.DLL:是处理.aspx文件的win32组件。其实IIS服务器是只能识别.html文件的,当IIS服务器发现被请求的文件是.aspx文件时,IIS服务器将其交给aspnet_isapi.dll来处理

  aspnet_wp.exe进程:ASP.NET框架进程,提供.net运行的托管环境,.net的CLR(公共语言运行时)就是寄存在此进程中。

 

// 摘要:
     //     定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
     public interface IHttpHandler
     {
         // 摘要:
         //     获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
         //
         // 返回结果:
         //     如果 System.Web.IHttpHandler 实例可再次使用,则为 true;否则为 false。
         bool IsReusable { get; }
 
         // 摘要:
         //     通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
         //
         // 参数:
         //   context:
         //     System.Web.HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session
         //     和 Server)的引用。
         void ProcessRequest(HttpContext context);
     }

  ProcessRequest方法是我们要写的逻辑,它的参数是当前请求的上下文,例如,你要访问http://localhost:3333/home/index,它的context就是当前

Request的上下文,而如果我们在httphandler里针对一个扩展名进行策略,如jpg,gif,那么,当WEB去渲染这些文件这前,将会首先处理httphandler中的
ProcessRequest方法,然后,如果不符合条件,你可以在页面上渲染你自己规定的信息,如果没有问题,再显示真实的图片!
这其实就是一个图片的防盗链技术,呵呵!效果如图:

而在页面上显示的图像路径还真实的:

这说明,httphandler是在处理这个物理文件之前,重新把另一个文件渲染上去了,呵呵
代码如下:
/// <summary>
     /// 图片防盗链
     /// </summary>
     public class ImgHandler : IHttpHandler
     {
         const string errImg = "/Content/daolian.jpg";
         public void ProcessRequest(HttpContext context)
         {
             // 获取文件服务器端物理路径
             string FileName = context.Server.MapPath(context.Request.FilePath);
             // 如果UrlReferrer为空,则显示一张默认的禁止盗链的图片
             if (context.Request.UrlReferrer == null || context.Request.UrlReferrer.Host == null)
             {
                 context.Response.ContentType = "image/JPEG";
                 context.Response.WriteFile(errImg);
             }
             else
             {
                 if (context.Request.UrlReferrer.Host.IndexOf("eee114.com") > 0)
                 {
                     context.Response.ContentType = "image/JPEG";
                     context.Response.WriteFile(FileName);
                 }
                 else
                 {
                     context.Response.ContentType = "image/JPEG";
                     context.Response.WriteFile(errImg);
                 }
             }
         }
 
         public bool IsReusable
         {
             get { return true; }
         }
     }

  在WWW网站的web.config中的<system.web>节点去调用它

   <!-- HttpHandlers对请求的扩展名进行处理 -->
    <httpHandlers>
      <add path="*.jpg,*.jpeg,*.gif,*.png,*.bmp" verb="*" type="HttpHandler.ImgHandler,HttpHandler" />
    </httpHandlers>

而流媒体的防盗链也是一样的方法,当然如果希望你的流媒体需要满足某种条件的用户才能看到的话,也可以这样去干:

/// <summary>
     /// 流媒体防盗链
     /// </summary>
     public class VideoHandler : IHttpHandler
     {
         const string errVideo = "/Content/daolian.jpg";
         #region IHttpHandler 成员
 
         public bool IsReusable
         {
             get { return true; }
         }
 
         public void ProcessRequest(HttpContext context)
         {
             //验证符合访问媒体的用户权限
             if (context.Session == null
                 || context.Session["UserID"] == null
                 || Convert.ToInt32(context.Session["UserID"]) <= 0)
             {
                 context.Response.ContentType = "mpg4 video/mp4";
                 context.Response.WriteFile(errVideo);
             }
         }
 
         #endregion
     }

  web.config是它的入口,呵呵

   <!-- HttpHandlers对请求的扩展名进行处理 -->
    <httpHandlers>
         <add path="*.avi,*.mp4,*.3gp,*.flv" verb="*" type="HttpHandler.VideoHandler,HttpHandler" />
    </httpHandlers>

OK,这时,你的流媒体在访问和下载之前,也会进行验证,不满足,就会下载默认的了,呵呵!

看来在页面“请求之前”,发生的事确实不少呀!

posted @ 2012-12-25 11:32  AIの海雅  阅读(494)  评论(0编辑  收藏  举报