定義 身份驗證(Authentication):確定用戶是誰。 授權(Authorization):確定用戶能做什麼,不能做什麼。 身份驗證 WebApi 假定身份驗證發生在宿主程式稱中。對於 web-hosting,宿主是 IIS。這種情況下使用 HTTP Module 進行驗證。 驗證時,宿主會 ...
定義
身份驗證(Authentication):確定用戶是誰。
授權(Authorization):確定用戶能做什麼,不能做什麼。
身份驗證
WebApi 假定身份驗證發生在宿主程式稱中。對於 web-hosting,宿主是 IIS。這種情況下使用 HTTP Module 進行驗證。
驗證時,宿主會創建一個表示安全上下文的主體對象(實現 IPrincipal),將它附加到當前線程。主體對象包含一個存儲用戶信息的 Identity 對象。若驗證成功,Identity.IsAuthenticated 屬性將返回 true。
HTTP 消息處理程式(HTTP Message Handler)
可以用 HTTP 消息處理程式代替宿主進行身份驗證。這種情況下,由 HTTP 消息處理程式檢查請求並設置主體對象。
請考慮以下事項決定是否使用消息處理程式進行身份驗證:
- HTTP 模塊檢查所有經過 asp.net 管道的請求,消息處理程式只檢查路由到 WebAPI的請求。
- 可以為每個路由單獨設置消息處理程式。
- HTTP 模塊僅在 IIS 中可用。消息處理程式則與宿主無關,在 web-hosting 和 self-hosting 中均可用。
- HTTP 模塊參與IIS 日誌和審計等功能。
- HTTP模塊在管道之前運行,主體在消息處理程式運行之前不會設置,當響應離開 消息處理程式時,主體會恢覆成原來的那個。
一般來說,不需要自承載時,HTTP 模塊較好。
設置主體
進行自定義身份驗證時,應在兩個地方設置主體對象:
- Thread.CurrentPrincipal,這是 .net 中設置線程主體的標準方式。
- HttpContext.Current.User 這是特定於 ASP.NET 的屬性。
private void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } }
採用 web-hosting 時,必須同時設置兩處,避免安全上下文不一致。對於 self-hosting,HttpContext.Current 為 null,所以設置之前應進行檢查。
授權
授權發生在管道中更接近 controller 的位置。
- 授權篩選器(Authorization filter)在 action 之前運行。若請求未授權,返回錯誤,action 不運行。
- 在 action 內部,可以用 ApiController.User 屬性獲取主體對象,做進一步的控制。
[Authorize] 屬性
AuthorizeAttribute 是內置的授權篩選器。用戶未通過身份驗證時,它返回 HTTP 401 狀態碼。可以在全局,控制和 action 三個級別應用它。
在全局級別應用:
public static void Register(HttpConfiguration config) { config.Filters.Add(new AuthorizeAttribute()); }
在控制器級別應用:
[Authorize] public class ValuesController : ApiController { public HttpResponseMessage Get(int id) { ... } public HttpResponseMessage Post() { ... } }
在 Action 級別應用:
public class ValuesController : ApiController { public HttpResponseMessage Get() { ... } [Authorize] public HttpResponseMessage Post() { ... } }
在控制器上應用 [Authorize] 時,可以在 Action 上應用 [AllowAnonymous] 取消對某個 Action 的授權要求。上面的代碼可以改成下麵的形式:
[Authorize] public class ValuesController : ApiController { [AllowAnonymous] public HttpResponseMessage Get() { ... } public HttpResponseMessage Post() { ... } }
指定用戶和角色進行限制:
// 按用戶限制訪問 [Authorize(Users="Alice,Bob")] public class ValuesController : ApiController { } // 按角色限制訪問 [Authorize(Roles="Administrators")] public class ValuesController : ApiController { }
用於 WebAPI 的 AuthorizeAttribute 位於 System.Web.Http 命名空間。在 System.Web.Mvc 命名空間中有一個同名屬性,不可用於 WebAPI。
自定義授權篩選器
可從以下類型派生自定義授權篩選器
- AuthorizeAttribute,基於用戶和角色進行授權。
- AuthorizationFilterAttribute,不基於用戶和角色的同步授權。
- IAuthorizationFilter,實現此介面執行非同步授權邏輯。例如,授權邏輯中有對 IO 或網路的非同步調用。(CPU-bound的授權邏輯更適合從 AuthorizationFilterAttribute 派生,這樣不必寫非同步方法)。
下圖是 AuthorizeAttribute 類層次
在 Action 中執行驗證
可在控制器中檢查 ApiController.User 屬性,根據用戶和角色使用不同的邏輯。
public HttpResponseMessage Get() { if (User.IsInRole("Administrators")) { // ... } }
原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api