• httpModel 实现页面url加密


         这其实是以前工作中的一个功能,当时觉得很好奇,是如何实现自动加密页面中的url的,如GridView中的链接绑定等。通过加密后的url的表现形式就如page.aspx?EncodingQuery=2IYZ2UW1bS2rPAuKZf4WWw==。今天在复习asp.net的基础常识时,既然想起,就来看看是如何实现的(这里主要还是参考DC.Web.HttpCompress)。

        1、首先,新建一个asp.net网站项目,在默认的页面上我们来绑定一个Gridview控件。

       

    View Code
      <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Height="285px" Width="638px">
                <Columns>
                    <asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="~/page.aspx?id={0}" HeaderText="Title" DataTextField="Name" />
                </Columns>
            </asp:GridView>
        </div>

     2、 在页面的后台方法中进行绑定数据:

    View Code
     1    List<LinkModel> list = new List<LinkModel>(2);
     2                 list.Add(new LinkModel()
     3                     {
     4                         Id ="11",
     5                         Name = "ltq"
     6                     });
     7                 list.Add(new LinkModel()
     8                 {
     9                     Id = "12"
    10                     ,Name = "hb"
    11                 });
    12                 GridView1.DataSource = list;
    13                 GridView1.DataBind();

    3、 点击F5,然后查看生成的源代码:

    可以看到,这里还是原始的未加密的url字符串。

    4、 好,现在新增一个HttpModel.cs:

    View Code
      1    public class HttpModule : IHttpModule
      2     {
      3         public void Dispose()
      4         {
      5 
      6         }
      7 
      8         public void Init(HttpApplication context)
      9         {
     10             
     11             context.BeginRequest += context_BeginRequest;
     12            
     13             context.PostReleaseRequestState += context_PostReleaseRequestState;
     14         }
     15 
     16 
     17         void context_BeginRequest(object sender, EventArgs e)
     18         {
     19             HttpApplication app = (HttpApplication) sender;
     20             HttpContext context = app.Context;
     21             string currentPath = context.Request.Url.PathAndQuery;
     22             int index = currentPath.IndexOf("?EncodingQuery=");
     23             if(index>0)
     24             {
     25                 string eQuery = currentPath.Substring(index+1);
     26                 string encryptQuery = currentPath.Substring(index + 15);
     27                 string query = AESUtil.Decrypt(encryptQuery,CommonUtil.AesKey );
     28                 currentPath = currentPath.Replace(eQuery,   query);
     29                 context .RewritePath(currentPath);
     30             }
     31         }
     32        
     33         private void context_PostReleaseRequestState(object sender, EventArgs e)
     34         {
     35             HttpApplication app = (HttpApplication) sender;
     36           
     37             if (app.Request["HTTP_X_MICROSOFTAJAX"] != null)
     38                 return;
     39 
     40             // fix to handle caching appropriately
     41             // see http://www.pocketsoap.com/weblog/2003/07/1330.html
     42             // Note, this header is added only when the request
     43             // has the possibility of being compressed...
     44             // i.e. it is not added when the request is excluded from
     45             // compression by CompressionLevel, Path, or MimeType            
     46             string realPath = "";
     47             Configuration settings = null;
     48             // get the config settings
     49           
     50             app.Context.Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
     51             string acceptedTypes = app.Request.Headers["Accept-Encoding"];
     52 
     53             // if we couldn't find the header, bail out
     54             if (acceptedTypes == null)
     55                 return;
     56 
     57             // Current response stream
     58 
     59             //Stream baseStream = app.Response.Filter;
     60             CompressionPageFilter filter = new CompressionPageFilter(app.Response.Filter);
     61             filter .AesKey =CommonUtil .AesKey;
     62             
     63             filter.App = app;
     64             app.Response.Filter = filter;
     65 
     66             // check for buggy versions of Internet Explorer
     67             if (app.Context.Request.Browser.Browser == "IE")
     68             {
     69                 if (app.Context.Request.Browser.MajorVersion < 6)
     70                     return;
     71                 else if (app.Context.Request.Browser.MajorVersion == 6 &&
     72                          !string.IsNullOrEmpty(app.Context.Request.ServerVariables["HTTP_USER_AGENT"]) &&
     73                          app.Context.Request.ServerVariables["HTTP_USER_AGENT"].Contains("EV1"))
     74                     return;
     75             }
     76             acceptedTypes = acceptedTypes.ToLower();
     77           
     78             if (filter.Compress != "none")
     79                 app.Response.AppendHeader("Content-Encoding", filter.Compress);
     80         }
     81 
     82         private class CompressionPageFilter : Stream
     83         {
     84 
     85             public string AesKey { get; set; }
     86             private HttpApplication app;
     87 
     88             public HttpApplication App
     89             {
     90                 get { return app; }
     91                 set { app = value; }
     92             }
     93 
     94             private string compress = "none";
     95 
     96             public string Compress
     97             {
     98                 get { return compress; }
     99                 set { compress = value; }
    100             }
    101 
    102             private StringBuilder responseHtml;
    103 
    104      
    105 
    106             private const string _linkPattern =
    107                 "(?<HTML><a[^>]*href\\s*=\\s*[\\\"\\']?(?<HREF>[^\"'>\\s]*)[\\\"\\']?[^>]*>)";
    108 
    109             public CompressionPageFilter(Stream sink)
    110             {
    111                 _sink = sink;
    112                 responseHtml = new StringBuilder();
    113             }
    114 
    115             private Stream _sink;
    116 
    117             #region Properites
    118 
    119             public override bool CanRead
    120             {
    121                 get { return true; }
    122             }
    123 
    124             public override bool CanSeek
    125             {
    126                 get { return true; }
    127             }
    128 
    129             public override bool CanWrite
    130             {
    131                 get { return true; }
    132             }
    133 
    134             public override void Flush()
    135             {
    136                 _sink.Flush();
    137             }
    138 
    139             public override long Length
    140             {
    141                 get { return 0; }
    142             }
    143 
    144             private long _position;
    145 
    146             public override long Position
    147             {
    148                 get { return _position; }
    149                 set { _position = value; }
    150             }
    151 
    152             #endregion
    153 
    154             #region Methods
    155 
    156             public override int Read(byte[] buffer, int offset, int count)
    157             {
    158                 return _sink.Read(buffer, offset, count);
    159             }
    160 
    161             public override long Seek(long offset, SeekOrigin origin)
    162             {
    163                 return _sink.Seek(offset, origin);
    164             }
    165 
    166             public override void SetLength(long value)
    167             {
    168                 _sink.SetLength(value);
    169             }
    170 
    171             public override void Close()
    172             {
    173                 _sink.Close();
    174             }
    175 
    176             public override void Write(byte[] buffer, int offset, int count)
    177             {
    178                 string strBuffer = UTF8Encoding.UTF8.GetString(buffer, offset, count);
    179 
    180                 // ---------------------------------
    181                 // Wait for the closing </html> tag
    182                 // ---------------------------------
    183                 Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);
    184 
    185                 responseHtml.Append(strBuffer);
    186 
    187                 if (eof.IsMatch(strBuffer))
    188                 {
    189                     // when compressing the html, some end characters are cut off.  Add some spaces so it cuts the spaces off instead of important characters
    190                     responseHtml.Append(Environment.NewLine + Environment.NewLine + Environment.NewLine +
    191                                         Environment.NewLine + Environment.NewLine + Environment.NewLine +
    192                                         Environment.NewLine + Environment.NewLine);
    193                     string html = responseHtml.ToString();
    194 
    195                     // replace the css and js with HttpHandlers that compress the output       
    196                     html = ReplaceLink(html);
    197 
    198 
    199                     byte[] data = UTF8Encoding.UTF8.GetBytes(html);
    200 
    201 
    202                     _sink.Write(data, 0, data.Length);
    203                 }
    204             }
    205 
    206             public string ReplaceLink(string html)
    207             {
    208                 // create a list of the stylesheets
    209                 List<string> stylesheets = new List<string>();
    210                 // create a dictionary used for combining css in the same directory
    211                 Dictionary<string, List<string>> css = new Dictionary<string, List<string>>();
    212 
    213                 // create a base uri which will be used to get the uris to the css
    214                 Uri baseUri = new Uri(app.Request.Url.AbsoluteUri);
    215 
    216                 // loop through each match
    217                 foreach (Match match in Regex.Matches(html, _linkPattern, RegexOptions.IgnoreCase))
    218                 {
    219                     // this is the enire match and will be used to replace the link
    220                     string linkHtml = match.Groups[0].Value;
    221                     // this is the href of the link
    222                     string href = match.Groups[2].Value;
    223 
    224                     // get a uri from the base uri, this will resolve any relative and absolute links
    225                     Uri uri = new Uri(baseUri, href);
    226                     string file = "";
    227                     // check to see if it is a link to a local file
    228                     if (uri.Host == baseUri.Host)
    229                     {
    230                         // check to see if it is local to the application
    231                         if (uri.AbsolutePath.ToLower().StartsWith(app.Context.Request.ApplicationPath.ToLower()))
    232                         {
    233                             // this combines css files in the same directory into one file (actual combining done in HttpHandler)
    234                             int index = uri.AbsolutePath.LastIndexOf("/");
    235                             string path = uri.AbsolutePath.Substring(0, index + 1);
    236                             file = uri.AbsolutePath.Substring(index + 1);
    237                             if (!css.ContainsKey(path))
    238                                 css.Add(path, new List<string>());
    239                             css[path].Add(file + (href.Contains("?") ? href.Substring(href.IndexOf("?")) : ""));
    240                             // replace the origianl links with blanks
    241                             var query = uri.Query;
    242                             if (query != "")
    243                             {
    244                                 string temp = query.Substring(1);
    245                                 string encryQuery = "?EncodingQuery=" + AESUtil.Encrypt(temp, AesKey);
    246                                 string newlinkHtml = linkHtml.Replace(query, encryQuery);
    247                                 html = html.Replace(linkHtml, newlinkHtml);
    248 
    249                             }
    250 
    251                             continue;
    252                         }
    253                          
    254                     }
    255                 
    256                 }
    257 
    258                 return html;
    259             }
    260 
    261 
    262 
    263 
    264 
    265             #endregion
    266 
    267         }
    268     }

    代码较长,但应该很清晰,在代码中是通过AES加解密链接字符串的参数的。

    5、注册这个HttpModel,在web.config中添加即可:

    1   <system.webServer>
    2     <handlers>
    3     </handlers>
    4     <modules>
    5       <add name="HttpCompressModule" type="HttpModelTest.HttpModule"/>
    6     </modules>
    7   </system.webServer>

    因为是在Vs2012下进行的测试,配置文件与在iis6中的配置是不同的。

    6、再次F5进入调试,查看源代码:

    可以看到,这里的参数都已经被加密了。

    7、 我们再来测试看看能不能正确解密这个字符串,在page.aspx的后台代码中添加如下代码:

    1   protected void Page_Load(object sender, EventArgs e)
    2         {
    3             string id = Request["id"];
    4             Response.Write(id);
    5         }

    F5进入测试:

    可以看到,正确输出id值。

    8、总结:

    a)加解密算法的选择是否正确,这个还得研究,毕竟感觉加密后的url的字符太多了。

    b)正则获取url的是否正确,会不会把其他文本内容中的url也加密了?

    c)性能,每次这样的遍历页面,进行匹配,对性能的影响有多大?

  • 相关阅读:
    Tomcat 部署Solr 5.2.1
    使用浮点类型导致计算误差以及判断误差
    Interface 接口
    ASP.NET 使用JQuery取后台数据并绑定到前台
    JavaScript代码应该放哪才最合适?
    Java学习笔记五(内部类 )
    Java学习笔记四(代码块 )
    Java学习笔记三(对象的基本思想一)
    Java学习笔记二(基础语法)
    Java学习笔记一(基础知识)
  • 原文地址:https://www.cnblogs.com/liaotongquan/p/2991920.html
Copyright © 2020-2023  润新知