ASP.NET 如何有效的防止资源被盗(防盗链下载)

介绍
为了有效的防止通过其他的网站的链接直接下载你网站里文件或图片,可以使用防止盗链功能。防盗链有很多中方法,例如:只允许登录的用户才可以下载,或者只允许特定的经过授权的网站(域名)才可以下载等。

IHttpHandler
通过IHttpHandler可以编写自定义 HTTP 处理程序来处理特定的、预定义类型的 HTTP 请求。响应这些特定请求的是在 HttpHandler 类中定义的可执行代码,而不是常规的 ASP 或 ASP.NET网页。HTTP 处理程序向您提供一种方法,使您可以与 IIS Web 服务器的低级别的请求和响应服务交互,同时提供极其类似于 ISAPI 扩展但编程模型较为简单的功能。有关如何创建HTTP处理程序参见:如何自定义IHttpHandler http://dev.mjxy.cn/a-How-to-customize-the-IHttpHandler.aspx

示例

以下示例代码演示如何防止非来自于dev.mjxy.cn的域名下载文件。

    public class DownHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            string server = string.Empty;
            //获取外链主机(域名)名称
            if (context.Request.UrlReferrer != null) { server = context.Request.UrlReferrer.Host; }
            string domain = System.Configuration.ConfigurationManager.AppSettings["domain"].ToString();
            FileInfo fileInfo = new FileInfo(context.Request.PhysicalPath); //获取访问文件的实际物理路径
            if (server == domain) //比较是否是允许的域名
            {
                Debug.WriteLine(fileInfo.Extension);
                down(context.Request.Path);
            }
            else
            {
                context.Response.Write(string.Format("<script type='text/javascript'>alert('敏捷学院-技术资源库 提醒:{0} 盗链下载不被允许!自动转到http://dev.mjxy.cn搜索你要的文件!');window.location='http://dev.mjxy.cn/search.aspx?q={1}';</script>",server,fileInfo.Name));
                context.Response.End();
            }
        }

        //流下载
        public void down(string cc)
        {
            if (cc != "")
            {
                string path = System.Web.HttpContext.Current.Server.MapPath(cc);
                System.IO.FileInfo file = new System.IO.FileInfo(path);
                if (file.Exists)
                {
                    System.Web.HttpContext.Current.Response.Clear();
                    //指定下载的文件名称
                    System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(file.Name, Encoding.UTF8).Replace("+", "%20"));
                    //文件大小
                    System.Web.HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
                    //通用格式
                    System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
                    System.Web.HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
                    System.Web.HttpContext.Current.Response.Filter.Close();
                    System.Web.HttpContext.Current.Response.WriteFile(file.FullName);
                    System.Web.HttpContext.Current.Response.End();
                }
                else
                {
                    System.Web.HttpContext.Current.Response.Write("文件不存在");
                    System.Web.HttpContext.Current.Response.End();
                }
            }
        }
    }

context.Request.UrlReferrer 是获取有关客户端上次请求的 URL 的信息,该请求链接到当前的 URL。
context.Request.UrlReferrer.Host 在这里是获取主机(客户端访问的域名)名称。
HttpUtility.UrlEncode(file.Name, Encoding.UTF8).Replace("+", "%20") 是对下载文件名称编码。UrlEncode编码后会把文件名中的空格转换中+(+转换为%2b),但是浏览器是不能理解加号为空格的,所以在浏览器下载得到的文件,空格就变成了加号。UrlEncode 之后, 将 "+" 替换成 "%20",因为浏览器将%20转换为空格。
允许下载文件的主机我们在web.config中配置:

<appSettings>
    <!-- 允许下载的域名-->
    <add key="domain" value="dev.mjxy.cn"/>
</appSettings>
 

注册HTTP处理程序
修改web.config配置文件
IIS6

<httpHandlers>
      <!-- 防盗链下载-->
      <add verb="*" path="/uploadfiles/files/*.*" validate="false" type="KnownWebHandler.DownHandler,KnownWebHandler"/>
</httpHandlers>


IIS7

<system.webServer>
    <handlers>
     <!-- 防盗链下载-->
      <add name="download" verb="*" path="/uploadfiles/files/*.*" type="KnownWebHandler.DownHandler,KnownWebHandler"/>
</handlers>
</system.webServer>
 

path="/uploadfiles/files/*.*" 表示只有这里目录里的所有文件才使用KnownWebHandler HTTP处理程序处理。

参考资料
如何自定义IHttpHandler http://dev.mjxy.cn/a-How-to-customize-the-IHttpHandler.aspx
以流的方式下载文件,隐藏实际的下载路径 http://dev.mjxy.cn/a-Download-the-file-to-stream-download-hide-the-real-path.aspx
在ASP.NET中支持断点续传下载大文件 http://dev.mjxy.cn/a-Supported-in-the-ASPNET-HTTP-download-large-files.aspx
IHttpHandler 接口 http://msdn.microsoft.com/zh-cn/library/system.web.ihttphandler(VS.80).aspx
HTTP 处理程序和 HTTP 模块概述 http://msdn.microsoft.com/zh-cn/library/bb398986(VS.90).aspx

posted @ 2011-08-13 00:36  敏捷学院  阅读(2763)  评论(1编辑  收藏  举报