IdentityServer4 学习笔记-用户确认

283 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情

1. 授权上下文

用户确认(Consent) 在授权请求期间,如果IdentityServer需要用户同意,则浏览器将被重定向到同意页面。

同意用于允许最终用户授予客户端对资源(身份或API)的访问权限。仅对第三方客户端是必需的,并且可以在客户端设置上按客户端启用/禁用。

IdentityServer将returnUrl参数(可在用户交互选项上配置)传递到包含授权请求参数的同意页面。这些参数提供了同意页面的上下文,可以在交互服务的帮助下阅读。该GetAuthorizationContextAsyncAPI将返回的实例AuthorizationRequest

可以使用IClientStoreIResourceStore接口获取有关客户端或资源的其他详细信息。

该API允许'grantconsentasync'在交互服务页面通知identityserver同意的结果(这也可能是在客户端访问等)。

IdentityServer将暂时保留同意的结果。这种持久性默认使用cookie,因为它只需要持续足够长的时间来将结果传回给授权端点。这种临时持久性与用于“记住我的同意”功能的持久性不同(并且授权端点持续“记住我对用户的同意”)。如果您希望在同意页面和授权重定向之间使用其他一些持久性,那么您可以IMessageStore<ConsentResponse>在DI中实现并注册实现。

2. 将用户返回到授权端点

一旦同意页面通知IdentityServer结果,就可以将用户重定向回returnUrl。您的同意页面应通过验证returnUrl是否有效来防止打开重定向。这可以通过调用IsValidReturnUrl来完成。此外,如果GetAuthorizationContextAsync返回非null结果,那么您还可以信任returnUrl有效。

IdentityServer 默认以JWT(JSON Web令牌)格式发出访问令牌,每个相关平台都支持验证JWT令牌

保护基于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");
    });
});