在asp.net WebAPI 中 使用Forms認證和ModelValidata(模型驗證)

1、Forms認證

一、在webapi項目中啓用Forms認證

Why:爲何要在WebAPI中使用Forms認證?由於其它項目使用的是Forms認證。web

What:什麼是Forms認證?它在WebAPI中就是一個MessageHandle,具體請查找關鍵字「ASP.NET Formsapi

How:如何啓動Forms認證?瀏覽器

  最簡單的是經過配置啓動Forms認證:安全

1 <system.web>
2     <authentication mode="Forms">
3       <forms name=".FormsCookie" loginUrl="/login.aspx" protection="All" timeout="43200" path="/" defaultUrl="http://www.cnblogs.com" domain=".cnblogs.com" cookieless="UseCookies" />
4     </authentication>
5     <httpCookies httpOnlyCookies="true" />
6   </system.web>
7   <system.webServer>
View Code

  簡單說說Forms認證的工做原理:首先在管道中,Forms讀取請求中的相關的cookie,解密,進行認證,並把認證的結果寫到請求上下文和線程的Identity屬性中。而後請求繼續日後面走,最終生成的響應在管道中返回時,Forms會判斷若是響應爲401,那麼就location到配置中的loginUrl設置的地址,並改變status爲302。cookie

二、幾個Attribute

Why:爲何要認識Attribute?由於Forms認證的結果是寫到Identity屬性中,通常咱們要獲取該屬性,判斷是否定證成功,若是失敗返回401,等等進行不少處理。是否是很麻煩?對,封裝起來,本身寫一個嗎?固然能夠,其實微軟大法早就考慮好了,針對通常的場景的處理邏輯都封裝好了,他們分別叫作less

AuthorizeAttribute、AllowAnonymousAttribute,都是Attribute。dom

What:這些Attribute是什麼?顧名思義,AuthorizeAttribute只容許認證經過的請求,AllowAnonymousAttribute容許匿名請求。ide

How:那麼該怎麼用呢?很簡單他們能夠做用類型、方法上,因此能夠全局註冊、controller、action, so easy!ui

 

三、重寫unauthorize中驗證失敗方法

Why:由於若是response status == 401,那麼Forms會location到配置中的loginUrl,(即便沒有手動配置它,也會生成一個默認值「login.aspx」),而且設置status爲302。若是客戶端是瀏覽器的話,那麼就會直接進行跳轉而沒法捕獲這個狀態,這在不少場景下不合適,例如:spa(單頁應用)中,咱們不但願它自動跳轉到登錄頁面,而是給出提示,讓用戶本身選擇是否登陸。因此要重寫Forms中身份驗證失敗的處理邏輯。spa

How:在AuthorizationFilterAttribute中有個虛方法HandleUnauthorizedRequest,重寫它來實現自定義的處理邏輯。這樣的設計思路挺不錯,能夠多借鑑。

    /// <summary>
    /// If unauthorize return 403 instead of  401, avoid redirect.
    /// </summary>
    public class ForbiddenLocationAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            HttpResponseMessage response = new HttpResponseMessage();
            response.StatusCode = System.Net.HttpStatusCode.Forbidden;
            actionContext.Response = response;

        }
    }

使用403(Forbidden)來代替401,這樣就能夠避免Forms的自動跳轉了。雖然這樣作有些弊端,但這也不失爲一個有效的解決辦法。

2、ModelValidata(模型驗證)

一、Why

  凡有用戶輸入的地方都少不了參數驗證,這不光是個安全問題,也是爲了保證數據完整正確。

二、What

  WebAPI集成了模型驗證機制,當請求被action執行以前,有一個模型綁定的步驟,它就是匹配action的參數,具體細節就不說了,ModelValidata就是在這裏進行,它會根據Model中各個屬性的DataAnnotations(數據註解)來進行驗證,最終把結果保存在action的上下文的一個屬性中,即actionContext.ModelState.IsValid。

三、How

  a、爲Model設置DataAnnotations

  

public class BannerDto
    {
        [JsonProperty(PropertyName = "id")]
        [Required(ErrorMessage = "Id是必須的")]
        public Guid Id { get; set; }

        [JsonProperty(PropertyName = "title")]
        [Required(ErrorMessage = "標題不能爲空")]
        [MaxLength(200, ErrorMessage = "標題不能超過200個字符")]
        public string Title { get; set; }

        [JsonProperty(PropertyName = "src")]
        [Required(ErrorMessage = "圖片連接不能爲空")]
        [MaxLength(500, ErrorMessage = "圖片連接不能超過500個字符")]
        public string ImageUri { get; set; }

        [JsonProperty(PropertyName = "href")]
        [Required(ErrorMessage = "超連接不能爲空")]
        [MaxLength(500, ErrorMessage = "超連接不能超過500個字符")]
        public string Href { get; set; }

        [JsonIgnore]
        public Guid? AuthorityId { get; set; }

        [JsonIgnore]
        public bool IsDeleted { get; set; } = false;

        [JsonProperty(PropertyName ="createDate")]
        public DateTime CreateDate { get; set; }
    }

  ps:[JsonProperty]、[JsonIgnore]是指定Json序列化的一些相關設置,設置別名、忽略等等。返回優雅的變量的名稱,保證代碼風格。

  DataAnnotations的使用,請查看msdn,太簡單了。設置好約束條件和ErrorMessage,當驗證失敗了,就會返回ErrorMessage。

  b、使用Filter方式,爲Action添加驗證,好處就很少說了。

public class ValidataModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }

別忘了在HttpComfiguration中注入這個Filter

            //模型驗證
            config.Filters.Add(new ValidataModelAttribute());    

對於不但願不驗證的Action可使用OverrideActionFilters重寫上級設置的全部Fiters。

ModelValidate失敗的請求會獲得400的響應,同時全部ErrorMessage都會在響應報文中,例如:

{"Message":"The request is invalid.","ModelState":{"sub.Href":["超連接不可爲空"]}}
相關文章
相關標籤/搜索