WebApi系列~安全校驗中的防篡改和防複用

回到目錄html

web api愈來愈火,由於它的跨平臺,由於它的簡單,由於它支持xml,json等流行的數據協議,咱們在開發基於面向服務的API時,有個問題一直在困擾着咱們,那就是數據的安全,請求的安全,通常所說的安全也無非就是請求的防篡改和請求的防複用,例如,你向API發一個查詢用戶帳戶的請求,在這個過程當中,你可能要傳遞用戶ID,用戶所在項目ID等,而如今攔截工具如此盛行,很容易就能夠把它的請求攔截,而後篡改,再轉發,這樣你的API就是不安全的,而對於訂單,帳戶模塊這種糟糕的API設計更是致命的,可能引發的損失是不可預計的,是災難性的,拍拍腦子想一想就知道,你向項目提現10元,我把請求攔截把10改爲100000,那麼這個將是一個災難!web

防篡改

通常使用的方式就是把參數拼接,加上雙方約定的「密鑰」,加上你的當前項目AppKey,作一次MD5加密,這個過程生成的字符串咱們通常稱爲密文,而對應的可見參數咱們叫明文,其中明文和密文用於網絡傳輸,而密鑰存儲在本地和服務器,不能進行傳輸!算法

防複用

通常請求,被重複的使用,也是正常的,就上面的方式進行加密,就沒法解決防複用的問題,這時咱們須要在客戶端和服務端分別生成UTC的時間戳,這個UTC是防止你的客戶端與服務端不在同一個時區,呵呵,而後把時間戳timestamp拼在密文裏就能夠了,至於防複用的有效性,咱們能夠自定義,固然大叔定義的是秒,即同一秒內,請求能夠重複發送。數據庫

大叔API安全結構圖

web api核心安全校驗代碼片段json

代碼供你們參考和學習,正式的項目能夠根據本身公司的須要去設計api

 /// <summary>
    /// 功能:api數據安全性驗證
    /// 校驗方式:ciphertext=md5(form鍵的值拼接+timestamp+passkey),服務端用接收到的表單數據與時間戳和本身的passkey進行md5生成,最後比較值是否一致
    /// passkey爲私鑰,不用於網絡傳遞,你能夠將它與appKey進行關聯,appKey用來傳遞,服務器根據appKey去數據庫裏取對應的passkey而後進行比較
    /// 功能:請求惟一性,防僞造性
    /// timestamp:UTC時間戳,不用於網絡傳遞,在客戶端調用服務器時,服務器也生成yyyyMMddhhmmss的時間戳,而後進行計算,看是否過時
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class ApiValidateFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            #region 初始化
            var context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];//獲取傳統context
            var request = context.Request;//定義傳統request對象
            var paramStr = new StringBuilder();
            var coll = new NameValueCollection();
            if (request.HttpMethod.ToLower() == "get")
                coll = request.QueryString;
            else
                coll = request.Form;
            #endregion

            #region 解析XML配置文件
            var config = CacheConfigFile.ConfigFactory.Instance.GetConfig<ApiValidateModelConfig>().ApiValidateModelList.FirstOrDefault(i => i.AppKey == coll["AppKey"]);
            if (config == null)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("AppKey不是合併的,請先去組織生成有效的Key", Encoding.GetEncoding("UTF-8"))
                };
                base.OnActionExecuting(actionContext);
            }
            if (config.ExpireDate < DateTime.Now)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("AppKey不是合併的,密鑰已過時", Encoding.GetEncoding("UTF-8"))
                };
                base.OnActionExecuting(actionContext);
            }
            #endregion

            #region 驗證算法
            var keys = new List<string>();
            foreach (string param in coll.Keys)
            {
                if (!string.IsNullOrEmpty(param))
                {
                    keys.Add(param.ToLower());
                }

            }
            keys.Sort();
            foreach (string p in keys)
            {
                if (p != "ciphertext")
                {
                    if (!string.IsNullOrEmpty(coll[p]))
                    {
                        paramStr.Append(coll[p]);
                    }

                }
            }
            paramStr.Append(DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss"));
            paramStr.Append(config.PassKey);
            #endregion


            if (Lind.DDD.Utils.Encryptor.Utility.EncryptString(paramStr.ToString(), Lind.DDD.Utils.Encryptor.Utility.EncryptorType.MD5)
                != request["cipherText"])
            {

                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("驗證失敗,請求非法", Encoding.GetEncoding("UTF-8"))
                };
            }

            base.OnActionExecuting(actionContext);
        }
    }

在上的配置項大叔把它存儲到的XML裏,使用的是大叔本身封裝的XML緩存組件CacheConfigFile,文件第一次訪問會加載到內存,下次使用直接從內存返回,而當文件修改後,文件的最後更新時間發生變化,這時緩存過時,在生產緩存時,仍是採用了單例模式,緩存

這個在大叔框架裏常常被看到,呵呵。安全

回到目錄服務器

相關文章
相關標籤/搜索