一、创建IdentityServer4服务器
1、创建一个ASP.NET Core空项目
2、创建一个Config类
using IdentityServer4.Models; using System.Collections.Generic; namespace Sample { public static class Config { public static IEnumerable<ApiScope> ApiScopes => new ApiScope[] { new ApiScope{Name="sample_api",DisplayName="Sample Api"}, new ApiScope{Name="scope2",DisplayName="Scope"} }; public static IEnumerable<Client> Clients => new Client[] { new Client { ClientId="sample_Client", ClientName="Client Credentials Client", //客户端名称 AllowedGrantTypes=GrantTypes.ClientCredentials,//客户端验证(验证模式) ClientSecrets={new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256())}, AllowedScopes={ "sample_api" } //访问资源范围 } }; } }
3、配置服务和管道,IdentityServer4采用的中间件形式,必须进行管道配置
1)添加服务
public void ConfigureServices(IServiceCollection services) { var builder= services.AddIdentityServer();//添加服务 builder.AddDeveloperSigningCredential();//配置开发验证模式 builder.AddInMemoryApiScopes(Config.ApiScopes);//配置内存API资源形式 builder.AddInMemoryClients(Config.Clients);//配置内存客户端访问形式 }
2)注册应用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); }
4、测试https://localhost:5001/.well-known/openid-configuration进行GET请求,查看
2)使用https://localhost:5001/connect/token获取token
3)token为jwt加密,解析查看
二、创建ASP.NET Core API
1、nuget安装Microsoft.AspNetCore.Authentication.JwtBearer
编写API控制器
public class IdentityController : ControllerBase { [Route("api/Identity")] [Authorize] public IActionResult Get() { return new JsonResult( from claim in User.Claims select new{ claim.Type, claim.Value } ); } }
2、配置认证服务
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "https://localhost:5001"; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false }; }); }
3、将服务加入请求管道
app.UseAuthentication();
4、测试
三、创建客户端程序访问
测试客户端代码
var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } var tokenResponse = await client.RequestClientCredentialsTokenAsync( new ClientCredentialsTokenRequest { Address=disco.TokenEndpoint, ClientId= "sample_Client", ClientSecret= "511536EF-F270-4058-80CA-1C89C192F69A" }); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json);
测试结果
测试请求资源
var apiclient = new HttpClient(); apiclient.SetBearerToken(tokenResponse.AccessToken); var response = await apiclient.GetAsync("https://localhost:6001/api/Identity"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); return; } var context = await response.Content.ReadAsStringAsync(); Console.WriteLine(); Console.WriteLine(JArray.Parse(context)); Console.ReadLine();
配置API资源的授权
services.AddAuthorization(options => { options.AddPolicy("ApiScope", builder => { builder.RequireAuthenticatedUser(); builder.RequireClaim("scope", "sample_api"); }); });