Identity Server 4客戶端認證控制訪問API
- 2022 年 7 月 10 日
- 筆記
- .NET Core, Identity Server 4
項目源碼:
鏈接://pan.baidu.com/s/1H3Y0ct8xgfVkgq4XsniqFA
提取碼:nzl3
一、說明
我們將定義一個api和要訪問它的客戶端,客戶端將在identityser上請求訪問令牌,並使用訪問令牌調用api
二、項目結構與準備
1、創建項目QuickStartIdentityServer4的asp.net 3.1項目,埠號5001,NuGet: IdentityServer4
2、創建項目API的asp.net 3.1項目,埠號5000,NuGet: Microsoft.AspNetCore.Authentication.JwtBearer
3、創建項目Client控制台項目(sp.net 3.1),模擬客戶端請求,NuGet: IdentityModel
三、QuickStartIdentityServer4項目編碼
1、在QuickStartIdentityServer4項目中添加Config.cs文件
public static class Config { // 定義api範圍 public static IEnumerable<ApiScope> ApiScopes => new [] { new ApiScope { Name="sample_api", // 範圍名稱,自定義 DisplayName="Sample API" // 範圍顯示名稱,自定義 } }; // 定義客戶端 public static IEnumerable<Client> Clients => new[] { new Client { ClientId="sample_client", // 客戶端id ClientSecrets = { new Secret("sample_client_secret".Sha256()) // 客戶端秘鑰 }, AllowedGrantTypes=GrantTypes.ClientCredentials, //授權類型為客戶端 AllowedScopes={ "sample_api" } // 設置該客戶端允許訪問的api範圍 } }; }
2、在QuickStartIdentityServer4項目中Startup.cs文件添加配置
public void ConfigureServices(IServiceCollection services) { var builder=services.AddIdentityServer(); builder.AddDeveloperSigningCredential(); builder.AddInMemoryApiScopes(Config.ApiScopes); builder.AddInMemoryClients(Config.Clients); }
3、訪問//localhost:5001/.well-known/openid-configuration
4、訪問//localhost:5001/connect/token即可拿到令牌token
該token是基於jwt,我們可以在jwt官網進行查看驗證,如圖
四、API項目編碼
1、Startup.cs文件配置
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // 添加JWT認證方案 services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", option => { // OIDC服務地址 option.Authority = "//localhost:5001"; // 不使用Https option.RequireHttpsMetadata = false; // 設置JWT的驗證參數 option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() { // 因為使用的是api範圍訪問,該參數需設置false ValidateAudience=false }; }); // 添加api授權策略 services.AddAuthorization(options => { // "ApiScope"為策略名稱 options.AddPolicy("ApiScope", builder => { builder.RequireAuthenticatedUser(); // 鑒定claim是否存在 builder.RequireClaim("scope", "sample_api"); }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); // 認證 app.UseAuthentication(); // 授權 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); // 設置全局策略,應用於所有api //endpoints.MapControllers().RequireAuthorization("ApiScope"); }); }
2、添加控制器IdentityServerController並增加授權
[Route("IdentityServer")] [Authorize("ApiScope")] public class IdentityServerController : ControllerBase { public IActionResult Get() { return new JsonResult(from claim in User.Claims select new { claim.Type,claim.Value }); } }
3、拿到token並請求api
五、Client項目模擬客戶端請求
internal class Program { static async Task Main(string[] args) { var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("//localhost:5001"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } var tokenResponse = await client.RequestClientCredentialsTokenAsync( new ClientCredentialsTokenRequest { Address= disco.TokenEndpoint, ClientId= "sample_client", ClientSecret= "sample_client_secret" } ); if(tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); var apiClient = new HttpClient(); apiClient.SetBearerToken(tokenResponse.AccessToken); var response = await apiClient.PostAsync("//localhost:5000/IdentityServer", null); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); } Console.ReadKey(); } }
項目運行效果如圖
學習鏈接地址://www.cnblogs.com/stulzq/p/7495129.html