IdentityServer4(8)- 使用密碼認證方式控制API訪問(資源全部者密碼受權模式)

原文: IdentityServer4(8)- 使用密碼認證方式控制API訪問(資源全部者密碼受權模式)

一.前言

本文及IdentityServer這個系列使用的都是基於.net core 2.0的。上一篇博文在API項目中我使用了Microsoft.AspNetCore.Authentication.JwtBearer組件來代替IdentityServer4.AccessTokenValidation組件,今天(2017-9-12)我發現後者已經更新到了2.0.0,支持.net core 2.0,因此如今所使用的組件已經更新爲後者,在代碼裏我有詳細註釋。html

二.資源全部者密碼受權模式(ResourceOwnerPassword)

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

  • 爲資源全部者密碼受權添加支持
  • 添加對用戶相關服務的支持,這服務一般爲登陸 UI 所使用(咱們將在下一個快速入門中用到登陸 UI)
  • 爲基於測試用戶的身份信息服務添加支持(你將在下一個快速入門中學習更多與之相關的東西)

四.爲資源全部者密碼受權添加一個客戶端定義

你能夠經過修改 ·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 可以區分表明客戶端的調用和表明用戶的調用。

sub

下面這張圖,是理解的客戶端請求流程,

關於上圖的補充說明,這裏講一下。api資源收到第一個請求以後,會去id4服務器公鑰,而後用公鑰驗證token是否合法,若是合法進行後面後面的有效性驗證。有且只有第一個請求才會去id4服務器請求公鑰,後面的請求都會用第一次請求的公鑰來驗證,這也是jwt去中心化驗證的思想。

五.使用Postman調試

使用postman調用生成token接口須要配置以下參數:

最後github地址:https://github.com/stulzq/IdentityServer4.Samples/tree/master/Quickstarts/2_ResourceOwnerPasswords 若是你以爲對你有用,歡迎star

相關文章
相關標籤/搜索