2011-03-19 118 views
1

我试图通过实施EncryptedActionLink来加密URL参数,该加密链路返回带有加密参数“p”的链接到通用操作“ResolveUrl”。控制器应该接收请求并调用适当的操作,或将其重定向到实际操作,而不会稍后在地址栏中显示未加密的值(因此RedirectToAction不起作用)。使用这种方法如何加密MVC中的URL参数

public static MvcHtmlString EncryptedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) 
    { 
     var RouteValueDictionary = new RouteValueDictionary(routeValues); 

     RouteValueDictionary.Add("actionName", actionName); 
     RouteValueDictionary.Add("noise", new Random().Next(5000,10000)); 

     var routeValuesText = RouteTable.Routes.GetVirtualPath(null, RouteValueDictionary).VirtualPath;    
     var Encryption64 = new Encryption64(); 
     var routeValuesTextCrypto = Encryption64.Encrypt(routeValuesText, "ABC123AB"); 

     return htmlHelper.ActionLink(linkText, "ResolveUrl", controllerName, new { p = routeValuesTextCrypto }, htmlAttributes); 
    } 

,我得到以下网址:

到目前为止,我已经这样做了扩展方法

<%: Html.EncryptedActionLink("MyText", "MyAction", "MyContoller", new { Parameter1 = 123, Parameter2 = "String", Parameter3 = false }, null)%> 

http://localhost:21536/MyContoller/ResolveUrl?p=iqo6yhy0Zl3jZXdMmnJ9KdvQhqCb5X6gg19%2FqZ8XUe19r5PJ6xO84plZr1GUHCHNY9h2SDO1o4CaF9W2DdmpywXooEQ1S0rNYjpnH4s3wb%2FqM8sGxoqAqyIoC%2F2nqW7U 

现在,我所有的contollers从ContollerBase继承。在那里,我定义RESOLVEURL行动,因为这:

public ActionResult ResolveUrl(String p) 
     { 
      var Encryption64 = new Encryption64(); 
      var query = Encryption64.Decrypt(p, "ABC123AB"); 

      if (query.Length > 2) 
       query = query.Substring(2); 

      var tokens = query.Split(new String [] { "&" }, StringSplitOptions.RemoveEmptyEntries); 
      var RouteValueDictionary = new RouteValueDictionary(); 

      for (int i = 0; i < tokens.Count(); i++) 
      { 
       var centerPos = tokens[i].IndexOf("="); 
       RouteValueDictionary.Add(tokens[i].Substring(0,centerPos),tokens[i].Substring(centerPos+1)); 
      } 

      Type thisType = this.GetType(); 
      MethodInfo theMethod = thisType.GetMethod(RouteValueDictionary["actionName"].ToString()); 
      var theParameters = theMethod.GetParameters(); 
      var theParametersObject = new object[theParameters.Count()]; 

      System.ComponentModel.TypeConverter converter = new System.ComponentModel.TypeConverter(); 

      for (int i=0 ; i<theParameters.Count();i++) 
      { 
       theParametersObject[i] = converter.ConvertTo(RouteValueDictionary[theParameters[i].Name],theParameters[i].ParameterType); 
      } 

      return (ActionResult)theMethod.Invoke(this, theParametersObject); 
     } 

有关代码的事情是RESOLVEURL不起作用。首先,当一个动作有两个实现比例(POST/GET)时,抛出异常。而第二件失败的是参数类型转换(例如从字符串转换为可空类型)。

如何加密URL参数?我的代码有用吗?做这个的最好方式是什么?

+0

我假设你已经修改了你的路由来使用'p'参数作为必需的参数吗? – 2011-03-19 01:20:51

+0

当然,“p”是ResolveUrl所需的参数。 ResolveUrl会被执行,但由于投射和“超载”操作名称会导致错误 – 2011-03-19 01:29:06

+1

HTTPS是否可用?然后参数和除IP /端口以外的所有内容都会自动加密。 – SilverbackNet 2011-03-19 02:25:52

回答

0

如果您尝试加密url参数(路由值),您可以使用custom valuedatatrovrovider,它将自动解密操作中的值,而不会在地址栏中显示未加密的值。