在web api中進行統一安全驗證類DelegatingHandler ,


根據web api 官方參考文獻 總結出一下代碼舉例:

將 HTTP 響應消息的處理委托給另一處理程序(稱為“內部處理程序”)的 HTTP 處理程序的類型。

如何理解這句話的意思?

首先我們應知道Asp.Net Web Api 的http消息響應機制,這里我可以解釋為:消息管道串聯。官方代碼指出:public abstract class DelegatingHandler : System.Net.Http.HttpMessageHandler,

而具體實現“管道串聯”是通過DelegatingHandler這個類型來完成。

通過以上文檔得出疑問

當DelegatingHandler自己負責的消息處理任務完成之后可以委托另一個HttpMessagHandler進行后續的處理。

如果這個被委托的也是一個DelegatingHandler對象,不就可以組成一個委托鏈了嗎?而這個委托鏈不就是由一個個DelegatingHandler組成的消息處理管道嗎?

 以上問題我們可以從程序集 System.Net.Http.dll, v4.0.0.0中得到答案:
namespace System.Net.Http
{
    // 摘要: 
    //     被稱為內部處理程序的並將 HTTP 響應消息委托給另一處理程序的 HTTP 處理程序的基類型。
    public abstract class DelegatingHandler : HttpMessageHandler
    {
        // 摘要: 
        //     創建 System.Net.Http.DelegatingHandler 類的新實例。
        protected DelegatingHandler();
        //
        // 摘要: 
        //     創建特定內部處理程序的 System.Net.Http.DelegatingHandler 類的新實例。
        //
        // 參數: 
        //   innerHandler:
        //     負責處理 HTTP 響應消息的內部處理程序。
        protected DelegatingHandler(HttpMessageHandler innerHandler);

        // 摘要: 
        //     獲取或設置處理 HTTP 響應消息的內部處理程序。
        //
        // 返回結果: 
        //     返回 System.Net.Http.HttpMessageHandler。 HTTP 響應消息的內部處理程序。
        public HttpMessageHandler InnerHandler { get; set; }

        // 摘要: 
        //     釋放由 System.Net.Http.DelegatingHandler 使用的非托管資源,並可根據需要釋放托管資源。
        //
        // 參數: 
        //   disposing:
        //     如果為 true,則釋放托管資源和非托管資源;如果為 false,則僅釋放非托管資源。
        protected override void Dispose(bool disposing);
        //
        // 摘要: 
        //     以異步操作發送 HTTP 請求到內部管理器以發送到服務器。
        //
        // 參數: 
        //   request:
        //     要發送到服務器的 HTTP 請求消息。
        //
        //   cancellationToken:
        //     取消操作的取消標記。
        //
        // 返回結果: 
        //     返回 System.Threading.Tasks.Task<TResult>。 表示異步操作的任務對象。
        //
        // 異常: 
        //   System.ArgumentNullException:
        //     request 為 null。
        protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
    }
}

我們在此可以總結出,如ASP.NET Web API的消息處理管道均由DelegatingHandler組成(位於管道尾端的HttpMessageHandler除外),我們就可以根據其InnerHandler獲得對被委托的HttpMessageHandler對象的引用,由此便構成消息處理的鏈式結構。組成ASP.NET Web API核心框架的消息處理管道,

理論總結的差不多,那么下面我們就對該消息處理委托類進行消息自定義操作,

public class RequestMessageDelegatingHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken).ContinueWith((responseToCompleteTask) =>
            {
                //獲取URL參數
                NameValueCollection query = HttpUtility.ParseQueryString(request.RequestUri.Query);
                //獲取Post正文數據,比如json文本
                string fRequesContent = request.Content.ReadAsStringAsync().Result;

                //可以做一些其他安全驗證工作,比如Token驗證,簽名驗證。
                //可以在需要時自定義HTTP響應消息
                //return SendError("自定義的HTTP響應消息", HttpStatusCode.OK);


                HttpResponseMessage response = responseToCompleteTask.Result;
                HttpError error = null;
                if (response.TryGetContentValue<HttpError>(out error))
                {
                    //添加自定義錯誤處理
                    //error.Message = "請求失敗";
                }

                if (error != null)
                {
                    //記錄關鍵的異常信息
                    QWPlatform.SystemLibrary.LogManager.Logger.Instance.Error("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]404錯誤:請求數據" + error.Message);
                    //返回錯誤信息
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        //封裝處理異常信息,返回指定JSON對象
                        Content = new StringContent(new ZLSoft.CHSS.Web.Public.Library.BaseClass.AjaxResult(Common.Base.AjaxResultType.失敗, error.Message + "404").CreateResultString()), //Encoding.GetEncoding("UTF-8"), "application/json"
                        ReasonPhrase = "Exception"

                    });
                }
                else
                {
                    return response;
                }
            }, cancellationToken);
        }
    }

接下來,我們只需要把當前類注冊到 webapiconfig類當中。

public class WebAPIConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //跨域配置
            config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
            //  config.MapHttpAttributeRoutes();

            //注冊路由映射
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );
            config.MessageHandlers.Add(new RequestMessageDelegatingHandler()); 
} }

接下里就可以在 RequestMessageDelegatingHandler 中間寫好消息處理機制哪里進行統一的安全校驗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM