一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情
1. 授权上下文
用户确认(Consent) 在授权请求期间,如果IdentityServer需要用户同意,则浏览器将被重定向到同意页面。
同意用于允许最终用户授予客户端对资源(身份或API)的访问权限。仅对第三方客户端是必需的,并且可以在客户端设置上按客户端启用/禁用。
IdentityServer将returnUrl参数(可在用户交互选项上配置)传递到包含授权请求参数的同意页面。这些参数提供了同意页面的上下文,可以在交互服务的帮助下阅读。该GetAuthorizationContextAsyncAPI将返回的实例AuthorizationRequest。
可以使用IClientStore和IResourceStore接口获取有关客户端或资源的其他详细信息。
该API允许'grantconsentasync'在交互服务页面通知identityserver同意的结果(这也可能是在客户端访问等)。
IdentityServer将暂时保留同意的结果。这种持久性默认使用cookie,因为它只需要持续足够长的时间来将结果传回给授权端点。这种临时持久性与用于“记住我的同意”功能的持久性不同(并且授权端点持续“记住我对用户的同意”)。如果您希望在同意页面和授权重定向之间使用其他一些持久性,那么您可以IMessageStore<ConsentResponse>在DI中实现并注册实现。
2. 将用户返回到授权端点
一旦同意页面通知IdentityServer结果,就可以将用户重定向回returnUrl。您的同意页面应通过验证returnUrl是否有效来防止打开重定向。这可以通过调用IsValidReturnUrl来完成。此外,如果GetAuthorizationContextAsync返回非null结果,那么您还可以信任returnUrl有效。
IdentityServer 默认以JWT(JSON Web令牌)格式发出访问令牌,每个相关平台都支持验证JWT令牌
-
ASP.NET Core的JWT bearer authentication handler
-
NodeJS的jsonwebtoken
保护基于ASP.NET Core的API只需在DI中配置JWT承载认证处理程序,并将认证中间件添加到管道:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://demo.identityserver.io";
options.Audience = "api1";
});
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
app.UseMvc();
}
}
3.IdentityServer身份验证处理程序
我们的身份验证处理程序与上述处理程序的用途相同(实际上它在内部使用Microsoft JWT库),但添加了一些其他功能,对于比较简单的情况,处理程序配置看起来非常类似
- 支持JWT和参考令牌
- 用于引用标记的可扩展缓存
- 统一配置模型
- 范围验证
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://demo.identityserver.io";
options.ApiName = "api1";
});
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
app.UseMvc();
}
}
4. 支持引用标记
如果传入令牌不是JWT,我们的中间件将联系发现文档中的内省端点以验证令牌。由于内省端点需要身份验证,因此您需要提供已配置的API密钥
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://demo.identityserver.io";
options.ApiName = "api1";
options.ApiSecret = "secret";
})
通常,不想为每个传入请求执行到内省端点的往返。中间件有一个内置缓存,像下面这样启用,处理程序将使用在DI容器中注册的任何IDistributedCache实现(例如标准的MemoryDistributedCache)。
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://demo.identityserver.io";
options.ApiName = "api1";
options.ApiSecret = "secret";
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10);
})
6.验证范围
所述ApiName属性检查该令牌具有匹配观众(或短aud),如权利要求。
在IdentityServer中,您还可以将API细分为多个范围。如果需要该粒度,可以使用ASP.NET Core授权策略系统来检查范围。
services
.AddMvcCore(options =>
{
var policy = ScopePolicy.Create("scope1", "scope2");
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddJsonFormatters()
.AddAuthorization();
services.AddAuthorization(options =>
{
options.AddPolicy("myPolicy", builder =>
{
builder.RequireScope("scope1");
builder.RequireScope("scope2", "scope3");
});
});