IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)
一.前言
本文已更新到 .NET Core 2.2
本文包括后續的Demo都會放在github:https://github.com/stulzq/IdentityServer4.Samples (QuickStart的幾個Demo隨著本系列的更新,目前為從官方Demo倉庫的拷貝,防止本文和Demo不匹配,因為官方Demo和文檔一直在更新,本系列更新速度可能會慢一步)。
這里特別說明一下:快速入門以及Topic系列為了保持到最新,目前幾乎都是翻譯的官方文檔(以往的不適合最新版本就換掉了),需要深入一點的請看實戰系列。
二.使用客戶端認證保護API
此示例介紹了使用IdentityServer保護API的最基本場景。
在這種情況下,我們將定義一個API和要訪問它的客戶端。 客戶端將在IdentityServer上請求訪問令牌,并使用它來訪問API。
三.準備
創建一個名為QuickstartIdentityServer的ASP.NET Core Web 空項目(asp.net core 2.2),端口5000
創建一個名為Api的ASP.NET Core Web Api 項目(asp.net core 2.2),端口5001
創建一個名為Client的控制臺項目(.net core 2.2)
四.定義API、Identity資源
在QuickstartIdentityServer項目中添加一個Config.cs文件:
public static class Config{public static IEnumerable<IdentityResource> GetIdentityResources(){return new IdentityResource[]{new IdentityResources.OpenId()};}public static IEnumerable<ApiResource> GetApis(){return new List<ApiResource>{new ApiResource("api1", "My API")};}public static IEnumerable<Client> GetClients(){return new List<Client>{new Client{ClientId = "client",// no interactive user, use the clientid/secret for authenticationAllowedGrantTypes = GrantTypes.ClientCredentials,// secret for authenticationClientSecrets ={new Secret("secret".Sha256())},// scopes that client has access toAllowedScopes = { "api1" }}};}}五.定義客戶端
對于這種情況,客戶端將不具有交互式(人機交互)用戶,并將使用IdentityServer的客戶端模式進行身份驗證。 將以下代碼添加到Config.cs文件中:
public static IEnumerable<Client> GetClients() {return new List<Client>{new Client{ClientId = "client",// no interactive user, use the clientid/secret for authenticationAllowedGrantTypes = GrantTypes.ClientCredentials,// secret for authenticationClientSecrets ={new Secret("secret".Sha256())},// scopes that client has access toAllowedScopes = { "api1" }}}; }六.配置 IdentityServer
要配置IdentityServer以使用Scope和客戶端定義,您需要向ConfigureServices方法添加代碼。
Startup.cs
public void ConfigureServices(IServiceCollection services) {var builder = services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryApiResources(Config.GetApis()).AddInMemoryClients(Config.GetClients());// rest omitted }public void Configure(IApplicationBuilder app) {if (Environment.IsDevelopment()){app.UseDeveloperExceptionPage();}// uncomment if you want to support static files//app.UseStaticFiles();app.UseIdentityServer();// uncomment, if you wan to add an MVC-based UI//app.UseMvcWithDefaultRoute(); }運行此項目,打開瀏覽器訪問http://localhost:5000/.well-known/openid-configuration你將會看到IdentityServer的各種元數據信息。
首次啟動時,IdentityServer將為您創建一個開發人員簽名密鑰,它是一個名為tempkey.rsa的文件。 您不必將該文件檢入源代碼管理中,如果該文件不存在,將重新創建該文件。
七.添加API
在項目Api中添加一個Controller:IdentityController
[Route("identity")] [Authorize] public class IdentityController : ControllerBase {[HttpGet]public IActionResult Get(){return new JsonResult(from c in User.Claims select new { c.Type, c.Value });} }最后一步是將身份驗證服務添加到DI和身份驗證中間件到管道。 這些將:
- 驗證傳入令牌以確保它來自受信任的頒發者
- 驗證令牌是否有效用于此API(也稱為 audience)
將Startup更新為如下所示:
public class Startup {public void ConfigureServices(IServiceCollection services){services.AddMvcCore().AddAuthorization().AddJsonFormatters();services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>{options.Authority = "http://localhost:5000";options.RequireHttpsMetadata = false;options.Audience = "api1";});}public void Configure(IApplicationBuilder app){app.UseAuthentication();app.UseMvc();} }AddAuthentication 將身份認證服務添加到DI,并將“Bearer”配置為默認方案。 AddIdentityServerAuthentication 將 IdentityServer Token 認證處理程序添加到DI中以供身份認證服務使用。 UseAuthentication 將身份認證中間件添加到管道中,因此將在每次調用API時自動執行身份驗證。
如果在瀏覽器訪問(http:// localhost:5001/identity),你會得到HTTP 401的結果。 這意味著您的API需要憑據。
就是這樣,API現在受 IdentityServer 保護。
八.創建客戶端
為 "Client" 項目添加 Nuget 包:IdentityModel
IdentityModel 包括用于發現 IdentityServer 各個終結點(EndPoint)的客戶端庫。這樣您只需要知道 IdentityServer 的地址 - 可以從元數據中讀取實際的各個終結點地址:
// discover endpoints from metadata var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) {Console.WriteLine(disco.Error);return; }DiscoveryClient 已在最新版移除
接下來,您可以使用從 IdentityServer 元數據獲取到的Token終結點請求令牌:
// request token var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest {Address = disco.TokenEndpoint,ClientId = "client",ClientSecret = "secret",Scope = "api1" });if (tokenResponse.IsError) {Console.WriteLine(tokenResponse.Error);return; }Console.WriteLine(tokenResponse.Json);九.調用API
要將Token發送到API,通常使用HTTP Authorization標頭。 這是使用SetBearerToken擴展方法完成的:
// call api var client = new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken);var response = await client.GetAsync("http://localhost:5001/identity"); if (!response.IsSuccessStatusCode) {Console.WriteLine(response.StatusCode); } else {var content = await response.Content.ReadAsStringAsync();Console.WriteLine(JArray.Parse(content)); }輸出應如下所示:
默認情況下,Token將包含有關 Scope,生命周期(nbf和exp),客戶端ID(client_id)和頒發者名稱(iss)的身份信息單元(Claim)。
十.使用Postman調試
十一.項目所用代碼
github地址: https://github.com/stulzq/IdentityServer4.Samples/tree/master/Quickstarts/1_ClientCredentials
轉載于:https://www.cnblogs.com/stulzq/p/7495129.html
總結
以上是生活随笔為你收集整理的IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: File类使用
- 下一篇: 从源码分析java.lang.Strin