1. 程式人生 > >IdentityServer(11)- 使用Hybrid Flow並新增API訪問控制

IdentityServer(11)- 使用Hybrid Flow並新增API訪問控制

原文: IdentityServer(11)- 使用Hybrid Flow並新增API訪問控制

關於Hybrid Flow 和 implicit flow

我在前一篇文章使用OpenID Connect新增使用者認證中提到了implicit flow,那麼它們是什麼呢,它和Hybrid Flow有什麼不同呢,這裡簡單講一下。

Hybrid Flow 和 implicit flow 是OIDC(OpenID Connect,OAuth2裡面沒有Hybrid Flow)協議中的術語,Implicit Flow是指使用OAuth2的Implicit流程獲取Id Token和Access Token;Hybrid Flow是指混合Authorization Code Flow(OAuth授權碼流程)和Implici Flow。

在之前的文章,我們探索了API訪問控制和身份認證。 現在我們要把這兩個部分結合在一起。

OpenID Connect和OAuth 2.0組合的優點在於,您可以使用單一協議和令牌服務進行單一交換。

在前一篇文章中,我們使用了OpenID Connect implicit flow。 在implicit流程中,所有的Token都通過瀏覽器傳輸,這對於id token來說是完全不錯的。 現在我們也想要一個AccessToken。id token比身份令牌更加敏感,如果不需要,我們不想讓它們暴露於“外部”世界。 OpenID Connect包含一個名為“Hybrid Flow”的流程,它可以讓我們兩全其美,id token通過瀏覽器通道傳輸,因此客戶端可以在做更多的工作之前驗證它。 如果驗證成功,客戶端會通過後端通道使用Token服務來獲取AccessToken。

修改客戶端配置

沒有必要做太多的修改。 首先,我們希望允許客戶端使用Hybrid Flow,另外我們還希望客戶端允許伺服器到伺服器API呼叫,這些呼叫不在使用者的上下文中(這與我們的客戶端認證模式的quickstart非常相似)。 這是使用AllowedGrantTypes屬性表示的。

接下來我們需要新增一個客戶端金鑰。 這將用於反向檢索通道上的AccessToken。

最後,我們還讓客戶端訪問offline_access作用域 - 這允許為長時間的API訪問請求重新整理令牌:

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },

    RedirectUris           = { "http://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    },
    AllowOfflineAccess = true
};

修改MVC客戶端

在MVC客戶端的修改也是最小的 - ASP.NET Core OpenID Connect處理程式已經內建支援混合流程,所以我們只需要改變一些配置值。

我們配置ClientSecret金鑰和IdentityServer上匹配。 新增offline_accessapi1作用域,並將ResponseType設定為程式碼id_token(基本意思是“使用混合流”)

.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;

    options.Scope.Add("api1");
    options.Scope.Add("offline_access");
});

當你執行MVC客戶端時,不會有太大的區別,除了同意介面現在要求你提供額外的API和offline access訪問作用域。

使用訪問令牌

OpenID Connect中介軟體會自動為您儲存令牌(標識,訪問和重新整理)。 這就是SaveTokens設定的作用。

技術上,令牌儲存在cookie。 訪問它們的最簡單方法是使用Microsoft.AspNetCore.Authentication名稱空間的擴充套件方法。

例如在View上獲取Token:

<dt>access token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>

<dt>refresh token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

要使用訪問令牌訪問API,您只需檢索令牌,並將其設定在您的HttpClient上:

public async Task<IActionResult> CallApiUsingUserAccessToken()
{
    var accessToken = await HttpContext.GetTokenAsync("access_token");

    var client = new HttpClient();
    client.SetBearerToken(accessToken);
    var content = await client.GetStringAsync("http://localhost:5001/identity");

    ViewBag.Json = JArray.Parse(content).ToString();
    return View("json");
}

本文程式碼:https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/5_HybridFlowAuthenticationWithApiAccess