學習筆記之IdentityServer4(一)

二三事發表於2021-09-07

快速入門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.csStartup.cs- 主應用程式入口點

        Config.cs - IdentityServer 資源和客戶端配置檔案

      如果需要使用Visual Studio作為開發工具,我們還需要建立解決方案檔案,命令如下:

dotnet new sln -n Quickstart

       我們需要將檔案新增至解決方案,命令如下:(請注意路徑是否正確)

dotnet sln add .\src\IdentityServer\IdentityServer.csproj
  • 開始學習

     專案建立成功之後,將會為我們建立config 檔案,Config檔案的程式碼如下:

學習筆記之IdentityServer4(一)
 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 }
View Code
  • 自定義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程式碼,我們將其更新如下:

學習筆記之IdentityServer4(一)
 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 }
View Code

   AddAuthentication將身份驗證服務新增到 DI 並配置Bearer為預設方案。

   UseAuthentication 將身份驗證中介軟體新增到管道中,因此每次呼叫主機時都會自動執行身份驗證。

   UseAuthorization 新增授權中介軟體以確保匿名客戶端無法訪問我們的 API 端點。

   https://localhost:6001/identity在瀏覽器上導航到控制器應返回 401 狀態程式碼。這意味著您的 API 需要憑證並且現在受 IdentityServer 保護。

 

相關文章