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_access
和api1
作用域,並將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