Web服务器和File服务器防盗链最佳办法:

由于公司需求,我找了好几天的资料,终于有眉头啦!

首先我们在web服务器上有几个下载地址:

此时有三个下载地址!

地址下载地址时,我们进行判断该用户是否合法,如果合法则获取File服务器地址路径!

 

 Response.Redirect("http://192.168.1.52:8034/ceshi.zip?hash=" + link.Hash("down", "1", "a", "a"));

 

 

 

我这里是在同一台服务器的二个站点进行测试的!(不同服务器原理一样)

Web服务器:

1.类型必须和File服务器一致。

2.标识码可以给文件的url,唯一标识

3.浏览器类型

4.客户端IP

 

 public class link
    {
        /// <summary>
        /// 生成 验证Hash
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="id">标识</param>
        /// <param name="agent">浏览器类型</param>
        ///  <param name="IP">IP</param>
        /// <returns></returns>
        public static string Hash(string type, string id, string agent, string ip)
        {
            //得到:当前时间,和,减于基数的TimeSpan
            var now = DateTime.Now;
            var ts = now - new DateTime(now.Year, 1, 1, 0, 0, 0);

            //得到:总分钟数,余数,参于hash的值 (也可以按秒计算,随意)(我这是5分钟)
            int total = (int)ts.TotalMinutes;
            int mod = total % 5;
            int time = total - mod;

            //得到:浏览器信息,IP地址
            //string agent = Request.UserAgent;
            //string ip = Request.UserHostAddress;

            //Hash格式 (可以把几个参数调换位置 或 加一些混淆内容)(如果不要限制某一项,把参数去掉就可以了)
            string encrypt = "{type}{id}{time}{agent}{ip}";

            //替换相应的内容
            encrypt = encrypt.Replace("{type}", type);
            encrypt = encrypt.Replace("{id}", id);
            encrypt = encrypt.Replace("{time}", time.ToString());
            encrypt = encrypt.Replace("{agent}", agent);
            encrypt = encrypt.Replace("{ip}", ip);

            //算Md5 并转成小写
            return Md5Encrypt(encrypt).ToLower();
        }

        #region 生成给定字符串的 MD5 加密字符串
        /// <summary>
        /// 生成给定字符串的 MD5 加密字符串
        /// </summary>
        public static string Md5Encrypt(string str)
        {
            string cl = str;
            string pwd = "";
            MD5 md5 = MD5.Create();//实例化一个md5对像 
            // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择  
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
            // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得 
            for (int i = 0; i < s.Length; i++)
            {
                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
                pwd = pwd + s[i].ToString("X");

            }
            return pwd;
        }
        #endregion
}

 

 

 

 

File服务器:

1.首先要在File服务器上面配置

<httpModules> <add type="web.HttpModule" name="HttpModule"/></httpModules>

2.新建类HttpModule如下所示:

 

public class HttpModule : IHttpModule
    {

        /// <summary>
        /// 实现接口的Init方法
        /// </summary>
        /// <param name="context"></param>
        public void Init(HttpApplication context)
        {
            //  GeneralConfigInfo si = GeneralConfigs.GetConfig();
            //  if (si == null || si.UrlRewriterProvider == "asp.net")
            context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
        }
        /// <summary>
        /// 重写Url
        /// </summary>
        /// <param name="sender">事件的源</param>
        /// <param name="e">包含事件数据的 EventArgs</param>
        private void ReUrl_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = (HttpApplication)sender;
            HttpContext context = application.Context;
            //读文件参数,和数据的代码,省略,得到文件保存路径
            string file = context.Request.Url.AbsolutePath;

            //得到类型和标识和Hash
            string type = "Play";    //注意,这个和你生成Hash时候使用的 type 要一致
            //int id = Convert.ToInt32(context.Request.QueryString["hash"]);
            string hash = context.Request.QueryString["hash"];

            //生成新的hash
            string newHash = link.Hash(type, "1", "a", "a");   //此处的参数和Web服务器保持一致
            //判断两个hash是否一致,不区分大小写
            if (string.Compare(newHash, hash, true) != 0)
            {
                //context.Response.Redirect("http://localhost:8039/b.aspx");
                //不一致,提示错误
                context.Response.Write("请不要盗链本站文件!");
                context.Response.End();
            }
            else
            {
                //输出文件
                context.Response.WriteFile(file);
            }
        }
        /// <summary>
        /// 实现接口的Dispose方法
        /// </summary>
        public void Dispose()
        {
        }


    }

 

 

posted on 2010-07-15 13:19  酷&酷  阅读(3328)  评论(22编辑  收藏  举报