WebApi 身份驗證方式
asp.net WebApi 中有三種身份驗證方式
- 個人用戶賬戶。用戶可以在網站注冊,也可以使用 google, facebook 等外部服務登錄。
- 工作和學校賬戶。使用活動目錄,Office 365等方式進行身份驗證。
- Windows 身份驗證。在局域網中使用。
個人用戶賬戶方式下又又兩種登錄方式:
- 本地登錄。用戶在網站注冊,網站保存用戶的登錄名和密碼散列值。登錄時,用戶提供登錄名和密碼,網站使用 asp.net identity 系統進行身份驗證。
- 社交登錄。使用 google, facebook 等外部服務登錄。網站仍然為用戶在數據庫中創建一個記錄,但是不會保存憑據。用戶通過登錄外部服務進行身份驗證。
這兩種登錄方式的差別在於憑據流,不管采用哪個方式,WebApi 都使用 OAuth2 進行身份驗證。
OAuth2 術語
- Resource(資源)。受保護的數據。
- Resource Server(資源服務器)。承載資源的服務器。
- Resouce Owner(資源所有者)。可以授權訪問資源的實體,用戶是典型的資源所有者。
- Client(客戶端)。訪問資源的應用程序。
- Access token(訪問令牌)。允許對資源進行訪問的令牌。
- Bearer token(不記名令牌)。這是訪問令牌的一種,客戶端不需要對其進行加密鑰,不記名令牌應僅在 HTTPS 上使用,並且設置較短的有效時間。
- Authorization server(授權服務器)。發出令牌的服務器。
實踐中,資源訪問器和授權訪問器可以是同一個應用程序。
本地登錄的憑據流程
對於本地登錄方式,WebApi 使用 OAuth2 中定義的資源所有者密碼授權類型。這種授權類型適用於資源所有者十分信任客戶端的情形。
- 用戶在客戶端輸入登錄名和密碼。
- 客戶端將登錄名和密碼發送給授權服務器。
- 授權服務器對憑據進行驗證,返回訪問令牌。
- 客戶端訪問受保護的資源時,將令牌放在 HTTP Authorization 請求頭中。
下圖是實現這個流程的具體程序結構
在這里,WebApi的控制器是資源服務器。Authentication Filter 對令牌進行驗證,Authorization Filter 決定是否授權。授權服務器和 Authentication Filter 通過 OWIN 中間件處理 OAuth2 標准規定的細節。
AccountController 使用 asp.net identity 管理用戶數據。相關文件有:
- \App_Start\IdentityConfig.cs
- \Controllers\AccountController.cs
- \Models\IdentityModels.cs
- \Providers\ApplicationOAuthProvider.cs
配置授權服務器
在 Startup.Auth.cs 文件的 ConfigureAuth 方法中進行配置。
public void ConfigureAuth(IAppBuilder app) { // 將數據庫上下文和用戶管理器配置為對每個請求使用單個實例 app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); // 使應用程序可以使用 Cookie 來存儲已登錄用戶的信息 // 並使用 Cookie 來臨時存儲有關使用第三方登錄提供程序登錄的用戶的信息 app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // 針對基於 OAuth 的流配置應用程序 PublicClientId = "self"; OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"), Provider = new ApplicationOAuthProvider(PublicClientId), AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), //在生產模式下設 AllowInsecureHttp = false AllowInsecureHttp = true }; // 使應用程序可以使用不記名令牌來驗證用戶身份 app.UseOAuthBearerTokens(OAuthOptions); }
使用 TokenEndpointPath 屬性配置授權服務器的終結點,應用程序通過這個URL獲取不記名令牌。使用 Provider 屬性配置接入到 OWIN 中間件的提供程序,用來處理中間件引發的事件。
配置使用不記名令牌
在 WebAppiConfig.Register 方法中配置 WebApi 使用不記名令牌。
public static void Register(HttpConfiguration config) { // Web API 配置和服務 // 將 Web API 配置為僅使用不記名令牌身份驗證。 config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
這里使用 SuppressDefaultHostAuthentication 方法通知 web api 忽略請求進入webapi管道之前的驗證,包括 iis 和 owin 中間件。使用 HostAuthenticationFilter 類對不記名令牌進行驗證。
獲取令牌
獲取令牌的基本步驟為:
- 程序請求 ~/Token。
- OAuth 中間件調用提供程序的 GrantResourceOwnerCredentials 方法。
- 提供程序調用 ApplicationUserManager 驗證憑據,創建 claims identity。
- 如果驗證成功,提供程序創建身份驗證票(authentication ticket),身份驗證票用於生成令牌。
OAuth 中間件本身不了解用戶賬戶的任何信息。提供程序用來協調中間件和 ASP.NET Identity。
訪問資源
- HostAuthentication 過濾器調用 OAuth 中間件對令牌進行驗證
- 中間件將令牌轉換成 claims identity
- 此時,請求處於已驗證但未授權狀態
- authorization 過濾器檢查claims identity。如果 claims 授權用戶訪問這個資源,則請求通過驗證。默認情況下,只要請求已被驗證,AuthorizeAttribute 就會授權。但是,你可以通過角色或其他聲明進行驗證。
- 如果上述步驟成功,控制器返回受保護的資源。否則,返回 401 錯誤。
原文地址:http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api