IdentityServer是一个OpenID Connect提供者 - 它实现了OpenID Connect和OAuth 2.0协议。是一种向客户发放安全令牌的软件。html
官网给出的功能解释是:web
IdentityServe4的四种模式:api
如下是IdentityServer的一个大体流程图:安全
先在asp.net core咱们选中空模版。由于自己写的业务也很少,只是为了作token的认证处理,全部建这个作测试比较方便。服务器
何时都不要忘记添加引用哦:app
NuGet命令行:Install-Package IdentityServer4asp.net
固然你也能够这样:async
而后建立config.cs类来处理咱们的一些业务:ide
//定义范围 #region 定义要保护的资源(webapi) public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("FirstAPI", "API接口安全测试") }; } #endregion #region 定义可访问客户端 public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { //客户端id自定义 ClientId = "YbfTest", AllowedGrantTypes = GrantTypes.ClientCredentials, ////设置模式,客户端模式 // 加密验证 ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) }, // client能够访问的范围,在GetScopes方法定义的名字。 AllowedScopes = new List<string> { "FirstAPI" } } }; } #endregion
以上就是一个基本的处理类了。而后咱们开始在Startup.cs 配置IdentityServer4:函数
public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResources()) //配置资源 .AddInMemoryClients(Config.GetClients());//配置客户端 }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //将IddiTyServer添加到管道中。 app.UseIdentityServer(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); }
这样就能够启动项目了,确认项目启动完成后,还要确认服务是否开启成功:在地址后增长地址:/.well-known/openid-configuration 例如:
出现以上结果就是启动成功了。
固然你也可使用postMan测试工具测试:
须要输入
grant_type
为客户端受权client_credentials
,client_id
为Config
中配置的ClientId
Client_Secret为Config
中配置的
Secret
例如:
这个比较简单了,首先建立一个简单的webapi程序便可。
仍是老规矩咯iuput,何时都不要忘记引用:
经过nuget添加便可:IdentityServer4.AccessTokenValidation
而后点击肯定安装就能够了。
在Startup类里面的ConfigureServices方法里面添加注册
public void ConfigureServices(IServiceCollection services) { //注册IdentityServer services.AddAuthentication(config => { config.DefaultScheme = "Bearer"; //这个是access_token的类型,获取access_token的时候返回参数中的token_type一致 }).AddIdentityServerAuthentication(option => { option.ApiName = "FirstAPI"; //资源名称,认证服务注册的资源列表名称一致, option.Authority = "http://127.0.0.1:5000"; //认证服务的url option.RequireHttpsMetadata = false; //是否启用https }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
而后在在Startup的Configure方法里配置Authentication中间件:
//配置Authentication中间件 app.UseAuthentication();
而后添加一个控制器进行验证测试:
我这里写了一个获取value值简单检测一下。
// GET api/values [HttpGet] [Authorize] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; }
这里注意要添加[Authorize]特性。用来作验证是否有权限的。没有的话,以上作的没有意义。须要引用命名空间:using Microsoft.AspNetCore.Authorization;
看一下正确的请求结果:
若是不传token值请求:
注意这里就会返回401的未受权状态。
上面咱们使用的是postman请求的以演示程序是否建立成功,这里咱们假设一个用户的使用客户端,这里咱们建立一个控制台来模拟一下真实的小场景。
既然是控制台就没什么好说的直接上代码main函数:
Task.Run(async () => { //从元数据中发现终结点,查找IdentityServer var disco = await DiscoveryClient.GetAsync("http://127.0.0.1:5000"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } //向IdentityServer请求令牌 var tokenClient = new TokenClient(disco.TokenEndpoint, "YbfTest", "YbfTest123");//请求的客户资源 var tokenResponse = await tokenClient.RequestClientCredentialsAsync("FirstAPI");//运行的范围 if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); //访问Api var client = new HttpClient(); //把令牌添加进请求 //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken); //client.SetBearerToken(tokenResponse.AccessToken); client.SetToken("Bearer", tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:42033/api/values"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); } }); Console.ReadLine();
这里主要介绍一下请求资源时添加令牌主要有三种形式,我都在代码给出,根据api资源的注册形式选择适合的。api的注册我也写了两种形式。主要的区别就是token前面的Bearer,若是想写成自定义的和默认成Bearer就是这里的区分。
自定义就要使用:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken);
若是全局默认的形式就不比每次请求都要添加因此能够写成:
client.SetBearerToken(tokenResponse.AccessToken);
运行项目以后出现成功界面: