快速入門IdentityServer4
-
概述
-
- 將 IdentityServer 新增到 ASP.NET Core 應用程式
- 配置 IdentityServer
- 為各種客戶發行代幣
- 保護 Web 應用程式和 API
- 新增對基於 EntityFramework 的配置的支援
- 新增對 ASP.NET 標識的支援
- 準備
- 安裝模板
控制檯視窗輸入該命令,下載 IdentityServer 模板
dotnet new -i IdentityServer4.Templates //
-
- 建立專案
開啟控制檯視窗,請在控制檯視窗鍵入以下命令
md quickstart //建立資料夾,資料夾名稱quickstart cd quickstart //進入資料夾quickstart md src //建立資料夾,資料夾名稱src cd src //進入資料夾src dotnet new is4empty -n IdentityServer //建立空專案,專案名稱IdentityServer
命令執行完成後,將會建立以下檔案
IdentityServer.csproj
- 專案檔案和一個Properties\launchSettings.json
檔案
Program.cs
和Startup.cs
- 主應用程式入口點
Config.cs
- IdentityServer 資源和客戶端配置檔案
如果需要使用Visual Studio作為開發工具,我們還需要建立解決方案檔案,命令如下:
dotnet new sln -n Quickstart
我們需要將檔案新增至解決方案,命令如下:(請注意路徑是否正確)
dotnet sln add .\src\IdentityServer\IdentityServer.csproj
- 開始學習
專案建立成功之後,將會為我們建立config 檔案,Config檔案的程式碼如下:
1 using IdentityServer4.Models; 2 using System.Collections.Generic; 3 4 namespace IdentityServer 5 { 6 public static class Config 7 { 8 public static IEnumerable<IdentityResource> IdentityResources => 9 new IdentityResource[] 10 { 11 new IdentityResources.OpenId() 12 }; 13 14 public static IEnumerable<ApiScope> ApiScopes => 15 new ApiScope[] 16 { }; 17 18 public static IEnumerable<Client> Clients => 19 new Client[] 20 { }; 21 } 22 }
- 自定義API範圍
1 public static IEnumerable<ApiScope> ApiScopes => 2 new List<ApiScope> 3 { 4 new ApiScope("api1", "MyApiName") 5 };
//ApiScope建構函式提供兩個引數,第一個引數為name,第二個引數為displayname
如果您在生產環境種使用自定義API範圍,您為您的API提供一個邏輯名稱很重要,開發人員將使用它通過您的身份伺服器請求您的API,它應該用簡單的術語向開發人員描述您的api,displayname為使用者提供apiScope的描述名稱
- 定義客戶端
我們將要定義一個客戶端應用程式,我們將用它來訪問我們的API,對於這種情況,客戶端沒有互動式使用者,並將使用IdentityServer使用客戶端金鑰進行身份驗證。為此我們需要新增一個客戶端
1 public static IEnumerable<Client> Clients => 2 new[] 3 { 4 new Client 5 { 6 ClientId = "client", 7 8 AllowedGrantTypes=GrantTypes.ClientCredentials, 9 10 ClientSecrets = 11 { 12 new Secret("secret","sha256") 13 }, 14 AllowedScopes = { "api1" } 15 } 16 };
您可以將 ClientId 和 ClientSecret 視為應用程式本身的登入名和密碼。它向身份伺服器標識您的應用程式,以便它知道哪個應用程式正在嘗試連線到它。
- 配置身份伺服器
在Startup.cs檔案中的ConfigureServices方法種定義資源和客戶端,程式碼如下:
1 public void ConfigureServices(IServiceCollection services) 2 { 3 // uncomment, if you want to add an MVC-based UI 4 //services.AddControllersWithViews(); 5 6 var builder = services.AddIdentityServer(options => 7 { 8 // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html 9 options.EmitStaticAudienceClaim = true; 10 }) 11 .AddInMemoryIdentityResources(Config.IdentityResources) 12 .AddInMemoryApiScopes(Config.ApiScopes) 13 .AddInMemoryClients(Config.Clients); 14 15 // not recommended for production - you need to store your key material somewhere secure 16 builder.AddDeveloperSigningCredential(); 17 }
配置您的身份伺服器之後,訪問路徑https://localhost:5001/.well-known/openid-configuration,我們將會看到發現文件,發現文件是身份伺服器種的標準節點,您的客戶端和API將使用該文件來檢視必要的配置資料,節點文件如下:
1 { 2 "issuer":"https://localhost:5001", 3 "jwks_uri":"https://localhost:5001/.well-known/openid-configuration/jwks", 4 "authorization_endpoint":"https://localhost:5001/connect/authorize", 5 "token_endpoint":"https://localhost:5001/connect/token", 6 "userinfo_endpoint":"https://localhost:5001/connect/userinfo", 7 "end_session_endpoint":"https://localhost:5001/connect/endsession", 8 "check_session_iframe":"https://localhost:5001/connect/checksession", 9 "revocation_endpoint":"https://localhost:5001/connect/revocation", 10 "introspection_endpoint":"https://localhost:5001/connect/introspect", 11 "device_authorization_endpoint":"https://localhost:5001/connect/deviceauthorization", 12 "frontchannel_logout_supported":true, 13 "frontchannel_logout_session_supported":true, 14 "backchannel_logout_supported":true, 15 "backchannel_logout_session_supported":true, 16 "scopes_supported":[ 17 "openid", 18 "api1", 19 "offline_access" 20 ], 21 "claims_supported":[ 22 "sub" 23 ], 24 "grant_types_supported":[ 25 "authorization_code", 26 "client_credentials", 27 "refresh_token", 28 "implicit", 29 "urn:ietf:params:oauth:grant-type:device_code" 30 ], 31 "response_types_supported":[ 32 "code", 33 "token", 34 "id_token", 35 "id_token token", 36 "code id_token", 37 "code token", 38 "code id_token token" 39 ], 40 "response_modes_supported":[ 41 "form_post", 42 "query", 43 "fragment" 44 ], 45 "token_endpoint_auth_methods_supported":[ 46 "client_secret_basic", 47 "client_secret_post" 48 ], 49 "id_token_signing_alg_values_supported":[ 50 "RS256" 51 ], 52 "subject_types_supported":[ 53 "public" 54 ], 55 "code_challenge_methods_supported":[ 56 "plain", 57 "S256" 58 ], 59 "request_parameter_supported":true 60 }
在第一次啟動時,IdentityServer 會為你建立一個開發者簽名金鑰,它是一個名為tempkey.jwk
. 您不必將該檔案簽入您的原始碼管理,如果它不存在,它將被重新建立
- 新增API測試
建立API專案,命令如下:
dotnet new webapi -n Api
將API專案新增至解決方案
dotnet sln add .\src\Api\Api.csproj
修改API專案的應用配置,修改執行埠號,我們可以通過編輯Properties 資料夾中的launchSettings.json檔案來執行此操作,將應用程式的URL設定更改為:
"applicationUrl": "https://localhost:6001"
- 新增控制器
我們新建一個類,為IdentityController,此測試類將用於測試授權要求,以及通過API視覺化身份識別
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 using Microsoft.AspNetCore.Authorization; 6 using Microsoft.AspNetCore.Mvc; 7 8 namespace Api.Controllers 9 { 10 [Route("identity")] 11 [Authorize] 12 public class IdentityController: ControllerBase 13 { 14 public IActionResult Get() 15 { 16 return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); 17 } 18 } 19 }
新增NuGet包依賴專案:Microsoft.AspNetCore.Authentication.JwtBearer,我們可以手動新增,也可以執行如下命令:
dotnet add .\\src\\api\\Api.csproj package Microsoft.AspNetCore.Authentication.JwtBearer
- 配置
最後一步是將身份驗證服務新增到DI(依賴注入) 並將身份驗證中介軟體新增到管道中,這些操作將:
-
- 驗證傳入的令牌以確保它來自受信任者的發行者
- 驗證令牌是否有效與此API一起使用
我們檢視以下API中的Startup程式碼,我們將其更新如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 using Microsoft.AspNetCore.Builder; 6 using Microsoft.AspNetCore.Hosting; 7 using Microsoft.AspNetCore.HttpsPolicy; 8 using Microsoft.AspNetCore.Mvc; 9 using Microsoft.Extensions.Configuration; 10 using Microsoft.Extensions.DependencyInjection; 11 using Microsoft.Extensions.Hosting; 12 using Microsoft.Extensions.Logging; 13 using Microsoft.IdentityModel.Tokens; 14 using Microsoft.OpenApi.Models; 15 16 namespace Api 17 { 18 public class Startup 19 { 20 public Startup(IConfiguration configuration) 21 { 22 Configuration = configuration; 23 } 24 25 public IConfiguration Configuration { get; } 26 27 // This method gets called by the runtime. Use this method to add services to the container. 28 public void ConfigureServices(IServiceCollection services) 29 { 30 31 services.AddControllers(); 32 services.AddSwaggerGen(c => 33 { 34 c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" }); 35 }); 36 37 services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options => 38 { 39 options.Authority = "https://localhost:5001"; 40 41 options.TokenValidationParameters = new TokenValidationParameters 42 { 43 ValidateAudience = false 44 }; 45 }); 46 47 } 48 49 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 50 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 51 { 52 if (env.IsDevelopment()) 53 { 54 app.UseDeveloperExceptionPage(); 55 app.UseSwagger(); 56 app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Api v1")); 57 } 58 59 app.UseHttpsRedirection(); 60 61 app.UseRouting(); 62 63 app.UseAuthentication(); 64 app.UseAuthorization(); 65 66 app.UseEndpoints(endpoints => 67 { 68 endpoints.MapControllers(); 69 }); 70 71 } 72 } 73 }
AddAuthentication
將身份驗證服務新增到 DI 並配置Bearer
為預設方案。
UseAuthentication
將身份驗證中介軟體新增到管道中,因此每次呼叫主機時都會自動執行身份驗證。
UseAuthorization
新增授權中介軟體以確保匿名客戶端無法訪問我們的 API 端點。
https://localhost:6001/identity
在瀏覽器上導航到控制器應返回 401 狀態程式碼。這意味著您的 API 需要憑證並且現在受 IdentityServer 保護。