ASP.NET 防盗链源码

本文介绍了一种基于IHttpHandler的防盗链策略,通过配置web.config文件中的参数,实现了对特定文件名的过滤,限制非法链接访问。详细阐述了如何检查请求来源、判断文件类型并输出相应内容,同时提供了错误信息处理机制。
摘要由CSDN通过智能技术生成

/* 
 *  
 * 防盗链IHttpHandler 
 *  
 *  
 * 增加了对文件关键字的选择(即仅对文件名存在某些关键字或不存在某些关键字进行过滤) 
 * 设置web.config中<appSettings>节以下值 
 * string eWebapp_NoLink    如果文件名符合该正确表态式将进行过滤(不设置对所有进行过滤) 
 * string eWebapp_AllowLink            如果文件名符合该正确表态式将不进行过滤(优先权高于AllowLink,不设置则服从AllowLink) 
 * bool eWebapp_ AllowOnlyFile        如果为False,(默认true)则不允许用户直接对该文件进行访问建议为true 
 *  
 *  
 * :)以下设置均可省略,设置只是为了增加灵活性与体验 
 * eWebapp_NoLink_Message    错误信息提示:默认为Link From:域名 
 * eWebapp_Error_Width        错误信息提示图片宽 
 * eWebapp_Error_Height        错误信息提示图片高 
 *  
 *  
 *  
 * 
 * http://ewebapp.net  
 */ 


using System; 
using System.Web; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.IO; 
using System.Configuration; 
using System.Text.RegularExpressions; 

namespace eWebapp 

    /// <summary> 
    /// 防盗链IHttpHandler 
    /// 参考http://www.softat.org/archiver/tid-52114.html 
    /// 
    /// </summary> 
    public class NoLink : IHttpHandler 
    { 
        private string eWebapp_NoLink = string.Empty; 
        private string eWebapp_AllowLink = string.Empty; 
        private bool eWebapp_AllowOnlyFile = true; 

        private string eWebapp_NoLink_Message = string.Empty; 
        private bool error = false; 

        public NoLink() 
        { 
            // 
            // TODO: 在此处添加构造函数逻辑 
            // 
        } 

        public void ProcessRequest(HttpContext context) 
        { 
            eWebapp_NoLink_Message = ConfigurationSettings.AppSettings["eWebapp_NoLink_Message"]; 
             
             
            string myDomain = string.Empty; 

            error = errorLink(context,out myDomain);     

            if(Empty(eWebapp_NoLink_Message))  
            { 
                eWebapp_NoLink_Message = "Link from :" + myDomain; 
            } 



            if(error) 
            { 
                //Jpg(context.Response,eWebapp_NoLink_Message); 
                Jpg(context.Response,eWebapp_NoLink_Message); 
            } 
            else 
            { 
                 Real(context.Response,context.Request); 
            } 

        } 

        public bool IsReusable 
        { 
            get 

            { 
                return true; 
            } 
        } 


        /// <summary> 
        /// 输出错误信息 
        /// </summary> 
        /// <param name="Response"></param> 
        /// <param name="_word"></param> 
        private void Jpg(HttpResponse Response,string _word)  
        { 


            int myErrorWidth = _word.Length*15; 
            int myErrorHeight = 16; 
            try 
            { 
                int _myErrorWidth = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Width"]); 
                if(_myErrorWidth > 0 ) 
                { 
                    myErrorWidth = _myErrorWidth; 
                } 

            } 
            catch 
            { 

            } 
            try 
            { 
                int _myErrorHeight = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Height"]); 
                if(_myErrorHeight  > 0 ) 
                { 
                    myErrorHeight = _myErrorHeight; 
                } 
            } 
            catch 
            { 

            } 
            Bitmap Img=null; 
            Graphics g=null; 
            MemoryStream ms=null; 
            Img=new Bitmap(myErrorWidth,myErrorHeight); 
            g=Graphics.FromImage(Img); 
            g.Clear(Color.White); 
            Font f=new Font("Arial",9); 
            SolidBrush s=new SolidBrush(Color.Red); 
            g.DrawString(_word,f,s,3,3); 
            ms=new MemoryStream(); 
            Img.Save(ms,ImageFormat.Jpeg); 
            Response.ClearContent();  
            Response.ContentType="image/Gif"; 
            Response.BinaryWrite(ms.ToArray()); 
            g.Dispose(); 
            Img.Dispose(); 
            Response.End(); 
        } 

        /// <summary> 
        /// 输出真实文件 
        /// </summary> 
        /// <param name="response"></param> 
        /// <param name="context"></param> 
        private void Real(HttpResponse response,HttpRequest request) 
        { 
            FileInfo file = new System.IO.FileInfo(request.PhysicalPath); 

            response.Clear(); 

            response.AddHeader("Content-Disposition", "filename=" + file.Name); 

            response.AddHeader("Content-Length", file.Length.ToString()); 

            string fileExtension = file.Extension.ToLower(); 


            //这里选择输出的文件格式 
            //可以参考http://ewebapp.cnblogs.com/articles/234756.html增加对更多文件格式的支持. 

             
            switch (fileExtension) 
            { 

                case "mp3": 
                    response.ContentType = "audio/mpeg3"; 
                    break; 

                case "mpeg": 

                    response.ContentType = "video/mpeg"; 
                    break; 

                case "jpg": 

                    response.ContentType = "image/jpeg"; 
                    break; 

                case "bmp": 

                    response.ContentType = "image/bmp"; 
                    break; 

                case "gif": 

                    response.ContentType = "image/gif"; 
                    break; 

                case "doc": 

                    response.ContentType = "application/msword"; 

                    break; 
                case "css": 

                    response.ContentType = "text/css"; 
                    break; 

                default: 

                    response.ContentType = "application/octet-stream"; 
                    break; 

            } 
             

            response.WriteFile(file.FullName); 

            response.End(); 
        } 


        /// <summary> 
        /// 确认字符串是否为空 
        /// </summary> 
        /// <param name="_value"></param> 
        /// <returns></returns> 
        private bool Empty(string _value) 
        { 
            if(_value == null | _value == string.Empty | _value == "") 
            { 
                return true; 
            } 
            else 
            { 
                return false; 
            } 
        } 


        /// <summary> 
        /// 检查是否是非法链接 
        /// </summary> 
        /// <param name="context"></param> 
        /// <param name="_myDomain"></param> 
        /// <returns></returns> 
        private bool errorLink(HttpContext context,out string _myDomain) 
        { 
            HttpResponse response = context.Response; 
            string myDomain = context.Request.ServerVariables["SERVER_NAME"]; 
            _myDomain = myDomain ; 
            string myDomainIp = context.Request.UserHostAddress; 


            eWebapp_NoLink = ConfigurationSettings.AppSettings["eWebapp_NoLink"]; 
            eWebapp_AllowLink = ConfigurationSettings.AppSettings["eWebapp_AllowLink"]; 

            try 
            { 
                eWebapp_AllowOnlyFile = Convert.ToBoolean(ConfigurationSettings.AppSettings["eWebapp_AllowOnlyFile"]); 
            } 
            catch 
            { 
                eWebapp_AllowOnlyFile = true; 
            } 


            if(context.Request.UrlReferrer != null) 
            { 

                 
                //判定referDomain是否存在网站的IP或域名 
                string referDomain = context.Request.UrlReferrer.AbsoluteUri.Replace(context.Request.UrlReferrer.AbsolutePath,""); 
                string myPath  = context.Request.RawUrl; 

                if(referDomain.IndexOf(myDomainIp) >=0 | referDomain.IndexOf(myDomain)>=0) 
                { 
                    return false; 
                } 
                else 
                { 
                    //这里使用正则表达对规则进行匹配 
                    try 
                    { 
                        Regex myRegex ; 

                        //检查允许匹配 
                        if(!Empty(eWebapp_AllowLink)) 
                        { 
                             
                            myRegex = new Regex(eWebapp_AllowLink); 

                            if(myRegex.IsMatch(myPath)) 
                            { 
                                return false; 
                            } 

                        } 


                        //检查禁止匹配 
                        if(!Empty(eWebapp_NoLink)) 
                        { 

                            myRegex = new Regex(eWebapp_NoLink); 
                            if(myRegex.IsMatch(myPath)) 
                            { 
                                return true; 
                            } 
                            else 
                            { 
                                return false; 
                            } 

                        } 

                        return true; 

                    } 
                    catch 
                    { 
                        //如果匹配出错,链接错误 
                        return true; 
                    } 
                } 
            } 
            else 
            { 
                //是否允许直接访问文件 
                if(eWebapp_AllowOnlyFile) 
                { 
                    return false; 
                } 
                else 
                { 
                    return true; 
                } 
            } 

        } 

    } 

}

 

概述

HttpHandler是一个HTTP请求的真正处理中心,也正是在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。

 

IHttpHandler是什么

IHttpHandler定义了如果要实现一个HTTP请求的处理所必需实现的一些系统约定。HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

 

IHttpHandler如何处理HTTP请求

当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandler的ProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。

对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。所谓一个HttpHandlerFactory,所谓一个HttpHandlerFactory,是指当一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。

一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。

 

 

 

1.打开IIS管理,注册ISAPI映射,比如".jpg"等都指向那个ASPNET_ISAPI.dll,在你的c:\windows\microsoft.net\framework\v1.0.3705下面;
注意,不要勾选“检查文件是否存在”的选项。
2.打开你应用中的web.config,在system.web节中添加如下的话语:

        <httpHandlers>
       <add verb="*" path="*.jpg" type="IHTTPHandler实现的类, 该类所在的程序集" />
              </httpHandlers>
3.编写那个IHttpHandler类:
在ProcessRequest里面根据需要使用context.Response.BinaryWrite将图片的二进制数据打出去就可以了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值