【转】在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份驗(yàn)證
基于令牌的身份驗(yàn)證主要區(qū)別于以前常用的基于cookie的身份驗(yàn)證,基于cookie的身份驗(yàn)證在B/S架構(gòu)中使用比較多,但是在Web Api中因其特殊性,基于cookie的身份驗(yàn)證已經(jīng)不適合了,因?yàn)椴⒉皇敲恳粋€(gè)調(diào)用api的客戶端都是從瀏覽器發(fā)起,我們面臨的客戶端可能是手機(jī)、平板、或者app。
使用基于Token令牌的身份驗(yàn)證有一些好處:
- 服務(wù)器的可伸縮性:發(fā)送到服務(wù)器的令牌是自包含的,不依賴于共享會話存儲
- 松散耦合:前端應(yīng)用程序位于特定的身份驗(yàn)證機(jī)制耦合,令牌是從服務(wù)器生成的,并且API構(gòu)建方式可理解該令牌并進(jìn)行身份驗(yàn)證
- 適用于移動設(shè)備:cookie依賴于瀏覽器,存儲于本機(jī)平臺,使用token將簡化流程
構(gòu)建后端API
步驟一: 創(chuàng)建Web Api 項(xiàng)目
?
為了進(jìn)行代碼演示,創(chuàng)建一個(gè)相對比較干凈的環(huán)境,我們新建一個(gè)項(xiàng)目,演示本次功能,本文使用Visual Studio 2017和 .NTE Framework 4.7。
在Vs中選擇新建項(xiàng)目,選擇ASP.NET Web 應(yīng)用程序(.NET Framework) ,命名為OauthExample或者隨便你喜歡的名字,然后下一步,選擇空模板。ok
?
步驟二:安裝Owin包,并設(shè)置“StartUp”類
項(xiàng)目右鍵,管理Nuget程序包,分別安裝
Microsoft.AspNet.WebApi.Owin
Microsoft.Owin.Host.SystemWeb
也可以在程序包管理器輸入如下代碼安裝:
Install-Package Microsoft.AspNet.WebApi.Owin Install-Package Microsoft.Owin.Host.SystemWeb等待安裝完成。
右鍵項(xiàng)目,移除Global.asax,右鍵項(xiàng)目,添加OWIN StartUp 類,然后修改代碼如下:
?
using System.Web.Http; using Microsoft.Owin; using Owin;[assembly: OwinStartup(typeof(OAuthExample.Startup))]namespace OAuthExample {public class Startup{public void Configuration(IAppBuilder app){// 有關(guān)如何配置應(yīng)用程序的詳細(xì)信息,請?jiān)L問 https://go.microsoft.com/fwlink/?LinkID=316888HttpConfiguration config = new HttpConfiguration();WebApiConfig.Register(config);app.UseWebApi(config);}} }?
簡要說明
- assembly屬性設(shè)置了啟動時(shí)要觸發(fā)的類
- HttpConfiguration對象用于配置API路由等,我們將對象傳遞給Register方法
- UasWebApi接收對象config,該方法將把Web Api連接到我們的OWIN服務(wù)管道
完成后編譯一下,檢查是否能通過,如果有問題檢查一下Nuget包是否安裝正確。
?
步驟三:添加對OAuth承載令牌生成的支持
安裝Owin包,Microsoft.Owin.Security.OAuth,再次打開StartUp文件,修改代碼如下(斜體):
using System; using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Security.OAuth; using Owin;[assembly: OwinStartup(typeof(OAuthExample.Startup))]namespace OAuthExample {public class Startup{public void Configuration(IAppBuilder app){// 有關(guān)如何配置應(yīng)用程序的詳細(xì)信息,請?jiān)L問 https://go.microsoft.com/fwlink/?LinkID=316888OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,TokenEndpointPath = new PathString("/oauth/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new CustomAuthorizationServerProvider()};// Token Generationapp.UseOAuthAuthorizationServer(OAuthServerOptions);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());HttpConfiguration config = new HttpConfiguration();WebApiConfig.Register(config);app.UseWebApi(config);}} }在這里,我們從類“OAuthAuthorizationServerOptions”創(chuàng)建了新實(shí)例,并設(shè)置選項(xiàng)如下:
- 允許客戶端使用http協(xié)議請求
- 令牌生成路徑為"/oauth/token"?,即通過路徑host: port:/oauth/token 獲取令牌信息
- 設(shè)置令牌的有效時(shí)間為一天,如果用戶在令牌發(fā)出24小時(shí)候使用令牌進(jìn)行身份驗(yàn)證,請求將被拒絕,并返回401狀態(tài)碼
- 我們在名為“CustomAuthorizationServerProvider”的類中實(shí)現(xiàn)了如何用戶票據(jù)的驗(yàn)證和發(fā)放
最后我們將此選項(xiàng)傳遞給擴(kuò)展方法“ UseOAuthAuthorizationServer”,以便將身份驗(yàn)證中間件添加到管道中。
?
步驟四:實(shí)現(xiàn)“CustomAuthorizationServerProvider”類
在項(xiàng)目中添加名為“ Providers”的新文件夾,然后添加名為“ SimpleAuthorizationServerProvider”的新類,在下面粘貼代碼片段:
using System.Security.Claims; using System.Threading.Tasks; using Microsoft.Owin.Security.OAuth;namespace OAuthExample.Providers {public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider{/// <summary>/// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are/// present on the request. If the web application accepts Basic authentication credentials,/// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web/// application accepts "client_id" and "client_secret" as form encoded POST parameters,/// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body./// If context.Validated is not called the request will not proceed further./// </summary>/// <param name="context">The context of the event carries information in and results out.</param>public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){context.Validated();}/// <summary>/// Called when a request to the Token endpoint arrives with a "grant_type" of "password". This occurs when the user has provided name and password/// credentials directly into the client application's user interface, and the client application is using those to acquire an "access_token" and/// optional "refresh_token". If the web application supports the/// resource owner credentials grant type it must validate the context.Username and context.Password as appropriate. To issue an/// access token the context.Validated must be called with a new ticket containing the claims about the resource owner which should be associated/// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers./// The default behavior is to reject this grant type./// See also http://tools.ietf.org/html/rfc6749#section-4.3.2/// </summary>/// <param name="context">The context of the event carries information in and results out.</param>public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });//這里是驗(yàn)證用戶名和密碼,可以根據(jù)項(xiàng)目情況自己實(shí)現(xiàn)if (!(context.UserName == "zhangsan" && context.Password == "123456")){context.SetError("invalid_grant", "The user name or password is incorrect.");return;}//可以隨便添加var identity = new ClaimsIdentity(context.Options.AuthenticationType);identity.AddClaim(new Claim("sub", context.UserName));identity.AddClaim(new Claim("role", "user"));context.Validated(identity);}} }步驟五:允許ASP.NET Web Api跨域請求
使用nuget安裝程序包,Install-Package Microsoft.Owin.Cors
然后在Startup類中添加如下代碼,最終代碼如下:
using System; using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Security.OAuth; using OAuthExample.Providers; using Owin;[assembly: OwinStartup(typeof(OAuthExample.Startup))]namespace OAuthExample {public class Startup{public void Configuration(IAppBuilder app){// 有關(guān)如何配置應(yīng)用程序的詳細(xì)信息,請?jiān)L問 https://go.microsoft.com/fwlink/?LinkID=316888OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new CustomAuthorizationServerProvider()};// Token Generationapp.UseOAuthAuthorizationServer(OAuthServerOptions);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());HttpConfiguration config = new HttpConfiguration();WebApiConfig.Register(config);app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);app.UseWebApi(config);}} }代碼測試
我們添加一個(gè)測試空的Order控制,用來測試一下上面的實(shí)現(xiàn):
[RoutePrefix("api/Orders")]public class OrdersController : ApiController{[Authorize][Route("")]public IHttpActionResult Get(){return Ok(Order.CreateOrders());}}#region Helperspublic class Order{public int OrderID { get; set; }public string CustomerName { get; set; }public string ShipperCity { get; set; }public Boolean IsShipped { get; set; }public static List<Order> CreateOrders(){List<Order> OrderList = new List<Order> {new Order {OrderID = 10248, CustomerName = "Taiseer Joudeh", ShipperCity = "Amman", IsShipped = true },new Order {OrderID = 10249, CustomerName = "Ahmad Hasan", ShipperCity = "Dubai", IsShipped = false},new Order {OrderID = 10250,CustomerName = "Tamer Yaser", ShipperCity = "Jeddah", IsShipped = false },new Order {OrderID = 10251,CustomerName = "Lina Majed", ShipperCity = "Abu Dhabi", IsShipped = false},new Order {OrderID = 10252,CustomerName = "Yasmeen Rami", ShipperCity = "Kuwait", IsShipped = true}};return OrderList;}}#endregion?
下面使用PostMan進(jìn)行模擬測試.
在未授權(quán)時(shí),直接訪問?http://localhost:56638/api/orders得到如下結(jié)果:
模擬授權(quán)訪問,先獲取令牌:
?
將令牌附加到Order請求,再次嘗試訪問:
?
可以看到已經(jīng)能正常獲取到數(shù)據(jù),打開調(diào)試,看一下方法中的變量如下:
?
總結(jié)
一直覺得WebApi和MVC很多都一樣的東西,在實(shí)際應(yīng)用中還是有不少區(qū)別,關(guān)于OAuth、JWT等等在WebApi中使用較多,本文是參照文末連接做的一個(gè)總結(jié),細(xì)看下原po的時(shí)間都已經(jīng)是14年的文章了。馬上要aspnet core 3.2都要發(fā)布了,現(xiàn)在卻還在補(bǔ)以前的知識,慚愧的很!
?
參考鏈接:
?Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
Enable OAuth Refresh Tokens in AngularJS App using ASP .NET Web API 2, and Owin
總結(jié)
以上是生活随笔為你收集整理的【转】在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 地方债一般债和专项债的区别,这些地方赶
- 下一篇: 白户能办高额信用卡么 白户办高额信用卡方