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 @ 2010-07-15 15:09  rob_2010  阅读(342)  评论(0)    收藏  举报