對於一個Http請求如何保證它的安全,這已經不是一個新的話題,對於請求的安全我們通常考慮的無非就是"請求的被篡改性"和"請求的被複制性",第一個問題我們很容易實現,可以通過引數+金鑰的方式,而第二個問題就很難實現了,到目前為止也沒有一個統一的標準,今天我們要說的安全性,也主要針對的第一種來講的.
對於一個URL地址來說,可能是這樣的格式
http://www.domain.com?vid=1&type=3&main=ok
對上面地址進行安全防篡改之後,可能地址就變成了這樣
http://www.domain.com?vid=1&type=3&main=ok&cipherText=e10adc3949ba59abbe56e057f20f883e
其中cipherText我們叫做密文,它由所有引數名+引數值+鑰密再進行md5生成的,其中鑰密是不公開的,在資料傳遞過程中,只要修改任意引數,你生成的cipherText就與我們正確的值不同,這時,你的驗證就是不通過的,呵呵.
對此,我把這套邏輯進行了抽象,提取到了特性裡(過濾器),如果你的action需要進行這種安全性驗證的話,直接在方法上新增這個特性即可
/// <summary> /// api資料安全性驗證 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class ApiValidateFilter : System.Web.Mvc.ActionFilterAttribute { public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) { var request = filterContext.HttpContext.Request; var method = request.HttpMethod; var passKey = "tsingda123"; var paramStr = new StringBuilder(); foreach (string param in request.Form.Keys) { if (param != "cipherText") paramStr.Append(request.Form[param]); } paramStr.Append(passKey); if (VCommons.Encryptor.Utility.EncryptString(paramStr.ToString(), VCommons.Encryptor.Utility.EncryptorType.MD5) != request.Form["cipherText"]) { //驗證失敗 filterContext.HttpContext.Response.ContentType = "applicatin/json"; filterContext.HttpContext.Response.Write(VCommons.SerializeMemoryHelper.SerializeToJson(new { Message = "驗證失敗" })); filterContext.HttpContext.Response.End(); } else { base.OnActionExecuting(filterContext); } } }
使用時非常簡單,呵呵
[ApiValidateFilter] public JsonResult AddHello(string username, string password, string email) { return Json(new { Message = username + password + email }, JsonRequestBehavior.AllowGet); }
在系統架構的世界裡,我們需要的已經對問題的抽象,對程式碼的重構,這種重構是不斷的,反覆的,我一直不相信"有一次寫好的程式碼",程式碼是在不斷的重構中完美的!