本文及IdentityServer這個系列使用的都是基於.net core 2.0的。上一篇博文在API
項目中我使用了Microsoft.AspNetCore.Authentication.JwtBearer
組件來代替IdentityServer4.AccessTokenValidation
組件,今天(2017-9-12)我發現後者已經更新到了2.0.0,支持.net core 2.0,因此如今所使用的組件已經更新爲後者,在代碼裏我有詳細註釋。html
OAuth 2.0 資源全部者密碼模式受權容許一個客戶端發送用戶名和密碼到IdentityServer並得到一個表示該用戶的能夠用於訪問api的Token。git
該規範建議僅對「受信任」應用程序使用資源全部者密碼受權。 通常來講,當您要驗證用戶並請求訪問令牌時,一般使用交互式OpenID Connect流會更好。github
不過,這個受權類型容許咱們在 IdentityServer 快速入門中引入 用戶 的概念,這是咱們要展現它的緣由。api
就像基於內存存儲的資源(即 Scopes)和客戶端同樣,對於用戶也能夠這樣作。服務器
注意:查看基於 ASP.NET Identity 的快速入門以得到更多關於如何正確存儲和管理用戶帳戶的信息。post
TestUser
類型表示一個測試用戶及其身份信息。讓咱們向配置類(若是你有嚴格按照順序進行演練,那麼配置類應該在 QuickstartIdentityServer 項目的 Config.cs 文件中)中添加如下代碼以建立一對用戶:學習
首先添加如下語句 到Config.cs
文件中:測試
public static List<TestUser> GetUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "alice", Password = "password" }, new TestUser { SubjectId = "2", Username = "bob", Password = "password" } }; }
而後將測試用戶註冊到 IdentityServer:ui
public void ConfigureServices(IServiceCollection services) { // 使用內存存儲,密鑰,客戶端和資源來配置身份服務器。 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResources())//添加api資源 .AddInMemoryClients(Config.GetClients())//添加客戶端 .AddTestUsers(Config.GetUsers()); //添加測試用戶 }
AddTestUsers 方法幫咱們作了如下幾件事:.net
你能夠經過修改 ·AllowedGrantTypes· 屬性簡單地添加對已有客戶端受權類型的支持。
一般你會想要爲資源全部者用例建立獨立的客戶端,添加如下代碼到你配置中的客戶端定義中:
// client want to access resources (aka scopes) public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "client", // 沒有交互性用戶,使用 clientid/secret 實現認證。 AllowedGrantTypes = GrantTypes.ClientCredentials, // 用於認證的密碼 ClientSecrets = { new Secret("secret".Sha256()) }, // 客戶端有權訪問的範圍(Scopes) AllowedScopes = { "api1" } }, // resource owner password grant client new Client { ClientId = "ro.client", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "api1" } } }; }
使用密碼受權請求一個令牌
客戶端看起來跟以前客戶端證書受權的客戶端是類似的。主要差異在於如今的客戶端將會以某種方式收集用戶密碼,而後在令牌請求期間發送到令牌服務。
IdentityModel 的 TokenClient
在這裏再次爲咱們提了供幫助:
// 從元數據中發現客戶端 var disco = await DiscoveryClient.GetAsync("http://localhost:5000"); // 請求令牌 var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret"); var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice", "password", "api1");//使用用戶名密碼 if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); Console.WriteLine("\n\n");
當你發送令牌到身份 API 端點的時候,你會發現與客戶端憑證受權
相比,資源全部者密碼受權有一個很小但很重要的區別。訪問令牌如今將包含一個 sub
信息,該信息是用戶的惟一標識。sub
信息能夠在調用 API 後經過檢查內容變量來被查看,而且也將被控制檯應用程序顯示到屏幕上。
sub
信息的存在(或缺失)使得 API 可以區分表明客戶端的調用和表明用戶的調用。
下面這張圖,是理解的客戶端請求流程,
關於上圖的補充說明,這裏講一下。api資源收到第一個請求以後,會去id4服務器公鑰,而後用公鑰驗證token是否合法,若是合法進行後面後面的有效性驗證。有且只有第一個請求才會去id4服務器請求公鑰,後面的請求都會用第一次請求的公鑰來驗證,這也是jwt去中心化驗證的思想。
使用postman調用生成token接口須要配置以下參數:
最後github地址:https://github.com/stulzq/IdentityServer4.Samples/tree/master/Quickstarts/2_ResourceOwnerPasswords 若是你以爲對你有用,歡迎star