WebApi系列~基(ji)于單請(qing)(qing)求封裝(zhuang)多請(qing)(qing)求的(de)設(she)(she)計~請(qing)(qing)求的(de)安(an)全性設(she)(she)計與實(shi)現
對于一(yi)(yi)(yi)個(ge)(ge)(ge)Http請求如何保證它的(de)(de)(de)(de)(de)安(an)(an)全(quan)(quan),這已經不是(shi)一(yi)(yi)(yi)個(ge)(ge)(ge)新的(de)(de)(de)(de)(de)話題,對于請求的(de)(de)(de)(de)(de)安(an)(an)全(quan)(quan)我們通常考慮的(de)(de)(de)(de)(de)無非就(jiu)是(shi)"請求的(de)(de)(de)(de)(de)被篡(cuan)改性"和"請求的(de)(de)(de)(de)(de)被復制性",第一(yi)(yi)(yi)個(ge)(ge)(ge)問(wen)題我們很容易實現(xian),可(ke)以(yi)通過參(can)數+密鑰的(de)(de)(de)(de)(de)方式,而(er)第二個(ge)(ge)(ge)問(wen)題就(jiu)很難實現(xian)了,到(dao)目前為止也(ye)沒有(you)一(yi)(yi)(yi)個(ge)(ge)(ge)統一(yi)(yi)(yi)的(de)(de)(de)(de)(de)標準,今(jin)天我們要(yao)說的(de)(de)(de)(de)(de)安(an)(an)全(quan)(quan)性,也(ye)主要(yao)針對的(de)(de)(de)(de)(de)第一(yi)(yi)(yi)種(zhong)來講(jiang)的(de)(de)(de)(de)(de).
對(dui)于一個URL地址來說(shuo),可能是(shi)這樣的格式(shi)
http://www.domain.com?vid=1&type=3&main=ok
對上面(mian)地(di)址進行安(an)全(quan)防篡改之(zhi)后(hou),可能地(di)址就變成了這樣
http://www.domain.com?vid=1&type=3&main=ok&cipherText=e10adc3949ba59abbe56e057f20f883e
其中cipherText我們叫做密文,它由所有參數名+參數值+鑰密再進行md5生成的,其中鑰密是不公開的,在數據傳遞過程中,只要修改任意參數,你生成的cipherText就與我們(men)正確的(de)值(zhi)不同,這時,你的(de)驗(yan)證(zheng)就是不通過的(de),呵呵.
對(dui)此,我把這(zhe)套邏輯進行了抽象,提取到了特性(xing)里(過(guo)濾器),如(ru)果你(ni)的(de)action需(xu)要進行這(zhe)種安全性(xing)驗證的(de)話,直接在方法上(shang)添加這(zhe)個特性(xing)即(ji)可
/// <summary> /// api數(shu)據安(an)全性驗證 /// </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 = "驗證(zheng)失敗" })); filterContext.HttpContext.Response.End(); } else { base.OnActionExecuting(filterContext); } } }
使用(yong)時非常簡(jian)單,呵呵
[ApiValidateFilter] public JsonResult AddHello(string username, string password, string email) { return Json(new { Message = username + password + email }, JsonRequestBehavior.AllowGet); }
在系統架構的(de)(de)世界里,我(wo)們需要的(de)(de)已(yi)經對問題的(de)(de)抽象,對代(dai)(dai)碼(ma)的(de)(de)重(zhong)構,這種重(zhong)構是不斷(duan)的(de)(de),反復的(de)(de),我(wo)一(yi)直(zhi)不相信"有一(yi)次寫好的(de)(de)代(dai)(dai)碼(ma)",代(dai)(dai)碼(ma)是在不斷(duan)的(de)(de)重(zhong)構中完美的(de)(de)!