IdentityServer4(一)使用客户端凭证方式
这个篇文章主要是记录自己参考官方文档搭建身份认证的过程
使用的.NET Core2.2
参考地址:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html
1.第一步,创建一个webapi的工程,要使用IDS4(IdentityServer4)做身份认证首先得在程序管理控制台导入IDS4的NuGet包:Install-Package IdentityServer4
2.因为客户端凭证的方式会在api根目录下生成一个tempkey.rsa文件,所以需要在在Starut.cs构造函数中注入IHostingEnvironment
1 public IHostingEnvironment Environment { get; } 2 public Startup(IConfiguration configuration, IHostingEnvironment environment) 3 { 4 Configuration = configuration; 5 Environment = environment; 6 }
3.导入IDS4的包之后我们需要在ConfigureServices中添加如下内容:
1 var builder = services.AddIdentityServer() 2 .AddInMemoryIdentityResources(Config.GetIdentityResources()) 3 .AddInMemoryApiResources(Config.GetApis()) 4 .AddInMemoryClients(Config.GetClients()) 5 //.AddTestUsers(Config.GetUsers()); 6 7 services.AddMvcCore() 8 .AddAuthorization() 9 .AddJsonFormatters(); 10 #region 客户端凭证的方式需要添加此处代码生成证书 11 if (Environment.IsDevelopment()) 12 { 13 builder.AddDeveloperSigningCredential(); 14 } 15 else 16 { 17 throw new Exception("need to configure key material"); 18 } 19 #endregion 20 21 services.AddAuthentication("Bearer") 22 .AddJwtBearer("Bearer", options => 23 { 24 options.Authority = "http://localhost:5000"; 25 //开发环境禁用了https,默认为开开启 26 options.RequireHttpsMetadata = false; 27 28 options.Audience = "api1"; 29 });
4.在Configure中添加identityServer中间件:
//在UseMvc之前即可 app.UseIdentityServer();
然后我们在VaulesController中修改下代码,在后面客户端的时候用来测试
[Route("api/[controller]")] [Authorize] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }
客户端需要导入IdentityModel Nuget包
下面代码中GetDiscoveryDocumentAsync()方法主要是从API服务的http://localhost:5000/.well-known/openid-configuration获取访问token的接口,即TokenEndpoint,debug可看到TokenEndpoint=http://localhost:5000/connect/token,经过验证直接将Addres赋值为http://localhost:5000/connect/token也是可以正常获取token的,查看IdentityModel源码也是在url中追加了/.well-known/openid-configuration
1 var _client = new HttpClient();1 2 3 var disco = _client.GetDiscoveryDocumentAsync("http://localhost:5000").Result; 4 if (disco.IsError) 5 { 6 Console.WriteLine(disco.Error); 7 }
1 var tokenResponse = _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest 2 { 3 4 Address = disco.TokenEndpoint,
//Address="http://localhost:5000/connect/token",//直接使用获取token的地址 5 ClientId = "client", 6 ClientSecret = "secret", 7 Scope = "api1" 8 }).Result; 9 10 if (tokenResponse.IsError) 11 { 12 Console.WriteLine(tokenResponse.Error); 13 Console.ReadKey(); 14 return; 15 } 16 Console.WriteLine("============================客户端获取token================================================"); 17 Console.WriteLine(tokenResponse.Json); 18 19 20 _client.SetBearerToken(tokenResponse.AccessToken); 21 var response = _client.GetAsync("http://localhost:5000/api/Values").Result; 22 if (!response.IsSuccessStatusCode) 23 { 24 Console.WriteLine(response.StatusCode); 25 } 26 else 27 { 28 var content = response.Content.ReadAsStringAsync().Result; 29 Console.WriteLine(JArray.Parse(content)); 30 }
以下是运行之后的结果