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 }
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() { } }