專案原始碼:
連結:https://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
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範圍 } }; }
public void ConfigureServices(IServiceCollection services) { var builder=services.AddIdentityServer(); builder.AddDeveloperSigningCredential(); builder.AddInMemoryApiScopes(Config.ApiScopes); builder.AddInMemoryClients(Config.Clients); }
該token是基於jwt,我們可以在jwt官網進行檢視驗證,如圖
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // 新增JWT認證方案 services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", option => { // OIDC服務地址 option.Authority = "http://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"); }); }
[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 }); } }
internal class Program { static async Task Main(string[] args) { var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://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("http://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(); } }
專案執行效果如圖
學習連結地址:https://www.cnblogs.com/stulzq/p/7495129.html