二.客户端凭据的认证方式

public static class Config{//定义APIpublic static IEnumerable ApiScopes =>new List{new ApiScope("api1", "My API")};//定义客户端// 定义访问 API 的客户端应用// 这种情况下,客户端没有交互式的用户,只能通过客户端密钥进行身份验证 。// ClientId 和 Client Secret 可以视为登录名和密码 。让身份认证服务器知道是哪个用户 。public static IEnumerable Clients => new List{new Client{// 定义一个客户端ClientId = "client",// 认证类型 。//使用客户端密钥的方式进行验证 。AllowedGrantTypes = GrantTypes.ClientCredentials,// 认证的密码ClientSecrets ={new Secret("secret".Sha256())},// 这个客户端端可以访问的 APIAllowedScopes = { "api1" }}};
2.在里面做调用设置
public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(IServiceCollection services){services.AddControllers();var builder = services.AddIdentityServer().AddInMemoryApiScopes(Config.ApiScopes) // 那个api可以使用.AddInMemoryClients(Config.Clients)// 哪个client可以使用.AddDeveloperSigningCredential() ;//解决连接不上的问题,实际中,签名需要一对公钥和私钥,他会帮我们将公钥和私钥存储到硬盘上}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseRouting();app.UseIdentityServer();//使用 Identity 4app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}
重生成,而使用命令行运行一下
… --urls *:5001
2.建立受保护的API
1.建立要访问受保护的
[ApiController]public class IdentityController : ControllerBase{[HttpGet("identity")][Authorize]public IActionResult Get(){return new JsonResult(from c in User.Claims select new { c.Type, c.Value });}[Authorize][HttpGet("test")]public string Getst(){return "受保护的 API 访问成功";}}
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};});// 允许检测客户端请求的令牌中是否存在作用域services.AddAuthorization(options =>{options.AddPolicy("ApiScope", policy =>{policy.RequireAuthenticatedUser();policy.RequireClaim("scope", "api1");});});}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseRouting();app.UseAuthentication();//每次都要执行身份验证.app.UseAuthorization(); //授权,确保匿名客户端无法访问我们的 api 端点app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}
3.建立用来访问的客户端
public class Program{// IdentityModel包括一个与发现端点一起使用的客户端库 。这样,您只需要知道IdentityServer的基地址-可以从元数据中读取实际的端点地址://找到授权的服务器public static async System.Threading.Tasks.Task Main(string[] args){//找到授权服务器var client = new HttpClient();var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");//异步的方法名前边必须声明 asyncif (disco.IsError){Console.WriteLine($"连接失败****{disco.Error}");return;}//向授权服务器请求 tokenvar tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest{Address = disco.TokenEndpoint,ClientId = "client",ClientSecret = "secret",Scope = "api1"});if (tokenResponse.IsError){Console.WriteLine("token返回错误", tokenResponse.Error);return;}Console.WriteLine(tokenResponse.Json);//将访问令牌发送给 APIvar apiClient = new HttpClient();apiClient.SetBearerToken(tokenResponse.AccessToken);var response = await apiClient.GetAsync("http://localhost:6001/test");if (!response.IsSuccessStatusCode){Console.WriteLine(response.StatusCode);Console.WriteLine("访问失败");}else{var content = await response.Content.ReadAsStringAsync();Console.WriteLine("访问成功");// Console.WriteLine(JArray.Parse(content));Console.WriteLine(content);}Console.ReadLine();}