移动软件开发工程师,网站加alt属性对优化有影响吗,帕绍网站建设,宿州网站制作公司书接上回#xff0c;我们将会正式开始介绍IdentityServer4。IdentityServer4是实现了OAuth2.0OpenId Connect两种协议的优秀第三方库,属于.net生态中的优秀成员。可以很容易集成至ASP.NET Core#xff0c;颁发token。使用Id4基本步骤如下#xff1a;**1.**在Startup.Configu… 书接上回我们将会正式开始介绍IdentityServer4。IdentityServer4是实现了OAuth2.0OpenId Connect两种协议的优秀第三方库,属于.net生态中的优秀成员。可以很容易集成至ASP.NET Core颁发token。使用Id4基本步骤如下**1.**在Startup.Configure方法中调用app.UseIdentityServer();
添加中间件把Id4添加至http请求处理管道,这使得Id4可以为OpenID Connect和OAuth2协议描述的端点(如/connect/token)请求提供服务。**2.**在Startup.ConfigureServices中注册IdentityServer4 services.AddIdentityServer(options{...});
**3.**配置Identity ServerIdentity资源表示提供给客户端进行用户识别的信息声明。声明可能包括用户名称、电子邮件地址等。API资源表示用户可通过访问令牌访问的受保护数据或功能。API 资源的一个示例是要求授权的 Web API或 API集合。用于签名的凭据credentials用户可能会请求访问的Identity资源和API资源会请求获取token的客户端用户信息的存储机制如ASP.NET Core Identity或者其他机制当你指明Id4使用的客户端和资源可以将IEnumerableT传递给接受内存中的客户端或资源存储的方法如果在更复杂的场景可以通过依赖注入的方式提供客户端和资源提供程序类型。IdentityServer4 使用自定义 IClientStore 类型提供的内存中资源和客户端的示例配置public IServiceProvider ConfigureServices(IServiceCollection services)
{//...services.AddSingletonIClientStore, CustomClientStore();services.AddIdentityServer().AddSigningCredential(CNsts).AddInMemoryApiResources(MyApiResourceProvider.GetAllResources()).AddAspNetIdentityApplicationUser();//...
}
经过上面的概述我们先易后难将从最简单的客户端凭证开始实战搭建IdentityServer4项目并以此保护api资源首先客户端凭证属于OAuth2.0的一种授权方式。主要是向IdentityServer发送post请求token?grant_typeclient_credentials client_idCLIENT_ID client_secretCLIENT_SECRET,获取access-token以此来访问api资源。在IdentityServer4中增加了Scope参数表明了客户端的访问权限1.安装Id4模板dotnet new -i IdentityServer4.Templates
AdminUI:测试生产环境需要交钱商业软件ASP.NET Core Identity结合ASP.NET Core IndentityEmpty空模板Entity Frame Store:使用ef数据持久化身份认证信息In-Memory Stores and Test Users:添加内存中的用户认证信息和测试用户Quickstart UI (UI assets only)UI2.创建ASP.NET Core应用,搭载Id42.1 创建项目使用IdentityServer4的空模板创建应用md quickstart
cd quickstartmd src
cd src#空模板 项目
dotnet new is4empty -n IdentityServer
The template IdentityServer4 Empty was created successfully.
项目添加解决方案cd ..
dotnet new sln -n QuickStartdotnet sln add .\IdentityServer\IdentityServer.csproj
2.2 修改launchSettings.json测试环境使用http删掉IIS相关的配置{profiles: {SelfHost: {commandName: Project,launchBrowser: true,launchUrl: .well-known/openid-configuration,environmentVariables: {ASPNETCORE_ENVIRONMENT: Development},applicationUrl: http://localhost:5001/}}
}
2.3 定义一个api scope上篇与前文都介绍过scope代表资源所有者在被保护资源那里的一些权限可以把被保护资源分为不同的scope具体的粒度由开发自定义。模板中ApiScope为空在Config.cs增加public static IEnumerableApiScope ApiScopes
new ApiScope[]
{//新增new ApiScope(api1, My API)
};
第二个参数是displayname2.4 定义一个客户端要让我们的IdentityServer给客户端颁发token就要让客户端在IdentityServer注册。客户端模板中的客户端与scope一样为空在Config.cs增加客户端代码如下 public static IEnumerableClient Clients new Client[]{new Client{ClientId client app,// no interactive user, use the clientid/secret for authenticationAllowedGrantTypes GrantTypes.ClientCredentials,// secret for authenticationClientSecrets {new Secret(secret-123456.Sha256())},// scopes that client has access toAllowedScopes { api1 }}};
“我们之后会增加这个定义的客户端这个客户端将会访问AllowedScopes指定的api scope。”注意在此场景下客户端跟用户是没有交互的身份认证是通过IdentityServer的客户密钥。官方描述你可以把ClientId和ClientSecret看作应用程序本身的登录名和密码。它向身份服务器表明您的应用程序的身份我是xx应用程序想访问服务器。2.5 注册IdentityServer注释模板代码Startup.ConfigureServices()所有代码增加代码加载定义的资源和客户端代码如下public void ConfigureServices(IServiceCollection services)
{var builder services.AddIdentityServer().AddInMemoryApiScopes(Config.ApiScopes).AddInMemoryClients(Config.Clients);// omitted for brevity
}
配置完成。运行并浏览器访问http://localhost:5001/.well-known/openid-configuration就能看到discovery document.它是IdentityServer中的标准端点客户端和APIs会使用它下载必要的配置数据容后再表在第一次启动时IdentityServer将创建一个开发者签名密钥它是一个名为tempkey.rsa的文件。您不必将该文件签入源代码版本控制如果不存在该文件它将被重新创建。3.创建webapi限制开始创建我们需要保护的api资源3.1 新建项目dotnet new webapi -n webapi
cd ..
dotnet sln add .\webapi\webapi.csproj
3.2 修改launchSettings.json{profiles: {Api: {commandName: Project,launchBrowser: true,applicationUrl: http://localhost:6001,environmentVariables: {ASPNETCORE_ENVIRONMENT: Development}}}
}
3.3 新增apiIdentityController.cs [Route(api/[controller])][ApiController]public class IdentityController : ControllerBase{[HttpGet]public IActionResult Get(){return new JsonResult(from c in User.Claims select new { c.Type, c.Value });}}
3.4 引入nuget包Microsoft.AspNetCore.Authentication.JwtBearer这个包是当收到请求时对授权头中JWT的具体身份认证dotnet add .\webapi\webapi.csproj package Microsoft.AspNetCore.Authentication.JwtBearer
3.5 注册服务和添加中间件最后一步是将身份认证服务添加到依赖注入中并将身份认证中间件添加到管道中。以便验证传入的token确保token来自可信的颁布者服务器验证这个token在这个api中使用是有效的(也就是受众)看代码{public void ConfigureServices(IServiceCollection services){services.AddControllers();services.AddAuthentication(Bearer).AddJwtBearer(Bearer, options {//token颁发者options.Authority http://localhost:5001;options.TokenValidationParameters new TokenValidationParameters{ValidateAudience false};options.RequireHttpsMetadata false;});services.AddAuthorization(options {options.AddPolicy(ApiScope, policy {policy.RequireAuthenticatedUser();//scopepolicy.RequireClaim(scope, api1);});});}public void Configure(IApplicationBuilder app){app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseEndpoints(endpoints {endpoints.MapControllers().RequireAuthorization(ApiScope);});}
}
AddAuthentication:增加认证服务到依赖注入注册Bearer作为默认schemeAddAuthorization:增加授权服务到依赖注入验证token中是否存在scope这里使用的是ASP.NET Core授权策略系统“这里实质是验证jwt中的payload的scope”RequireHttpsMetadata 用于测试目的将此参数设置为 false可在你没有证书的环境中进行测试。在实际部署中JWT 持有者令牌应始终只能通过 HTTPS 传递。UseAuthentication:添加认证中间件以便对host的每次调用自动执行身份认证此中间件准备就绪后会自动从授权标头中提取 JWT 令牌。然后对其进行反序列化、验证并将其存储为用户信息稍后供 MVC 操作或授权筛选器引用。“JWT 持有者身份验证中间件还可以支持更高级的方案例如颁发机构authority 不可用时使用本地证书验证令牌。对于此情景可以在 JwtBearerOptions 对象中指定 TokenValidationParameters 对象。”UseAuthorization:添加授权中间件以确保我们的api不会被匿名客户端访问RequireAuthorization(ApiScope):全局执行授权策略“除了全局以外还可以针对多有的api端点或者特定的controlleraction根据实际的业务场景灵活变化吧”访问http://localhost:6001/identity,返回状态码401这是api要求凭证所以现在api是被IdentityServer保护着4.创建客户端最后一步创建一个由IdentityServer管理的客户端并通过客户端请求access-token然后访问api4.1 新建项目dotnet new console -n Client
dotnet sln add .\Client\Client.csproj
4.2 引入nuget包需要引入IdentityModel包一个客户端类以请求disconvery endpointcd .\Client\
dotnet add package IdentityModel
4.3 编码-请求Idisconvery endpoint只需要知道IdentityServer的基础地址实际的各类端点地址就可以从元数据中读取 class Program{static async Task Main(string[] args){// discover endpoints from metadatavar client new HttpClient();var disco await client.GetDiscoveryDocumentAsync(http://localhost:5001);if (disco.IsError){Console.WriteLine(disco.Error);return;}}}
4.4 编码-请求access token这一步使用从discovery document中获取的信息向IdentityServer请求一个访问api1的token// request token
var tokenResponse await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{Address disco.TokenEndpoint,//在IdentityServer注册的id与secretClientId client app,ClientSecret secret-123456,Scope api1
});if (tokenResponse.IsError)
{Console.WriteLine(tokenResponse.Error);return;
}Console.WriteLine(tokenResponse.Json);
注意看这里的ClientIdClientSecret必须与2.4中定义客户端保持一致Scope也要与AllowedScopes保持一致。4.5 编码-调用api在这一步使用扩展方法SetBearerToken这个方法主要组装http请求授权头access token并以此请求访问api资源// call api
var apiClient new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);var response await apiClient.GetAsync(http://localhost:6001/api/identity);
if (!response.IsSuccessStatusCode)
{Console.WriteLine(response.StatusCode);
}
else
{var content await response.Content.ReadAsStringAsync();Console.WriteLine(JArray.Parse(content));
}
5.测试启动IdentityServercd .\IdentityServer\
dotnet run
启动webapicd .\webapi\
dotnet run
用vs启动client获取access-token我们通过http://jwt.calebb.net/解析这也是api返回的Claims“身份认证的中间对JWT进行了身份认证后会把解析到的Claims组装进HttpContext以供下一个中间件如授权中间件调用”接下来我们就去触发不同的错误去了解IdentityServer是如何工作的我选择其中几个比较有意义的测试5.1 使用一个无效客户端id或者密钥请求token没被注册的客户端访问时所以是invalid_client类比场景去办理门禁卡物业没找到你这个业主信息办个鬼呀5.2 在请求token时指定无效的scope请求token指定的scope在indentityserver中并不存在所以是invalid_scope类比场景去办理门禁卡小区一共10栋你去办11栋办个鬼呀5.3 请求api时不传入toekn不传入token那么webapi就没收到token所以返回Unauthorized未授权类比场景进入小区没有门禁肯定不让你进5.4 修改API对scope的验证要求被保护的资源webapi中配置plicy.RequireClaim(scope,api2);而客户端指定的scope是api1客户端是有access-token具有进入系统凭证但是只允许scope为api2的访问传入的时api1当然就返回Forbidden类比场景小区进入后进入单元楼明明是3栋2单元的楼宇但是你的门禁只能针对3栋1单元当然也不会刷开2单元的大门参考链接https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html#source-code长按二维码关注点外卖先领券