ASP.NET Core 2.0 身份验证中间件

Posted

技术标签:

【中文标题】ASP.NET Core 2.0 身份验证中间件【英文标题】:ASP.NET Core 2.0 authentication middleware 【发布时间】:2018-01-30 00:26:44 【问题描述】:

Core 1.1 遵循@blowdart 的建议并实现了自定义中间件:

https://***.com/a/31465227/29821

它是这样工作的:

    中间件已运行。从请求标头中提取了一个令牌。 验证令牌,如果有效,则构建包含多个声明的身份 (ClaimsIdentity),然后通过 HttpContext.User.AddIdentity() 添加; 在使用 services.AddAuthorization 的 ConfigureServices 中,我添加了一个策略来要求中间件提供的声明。 在控制器/操作中,我将使用 [Authorize(Roles = "some role that the middleware added")]

这有点适用于 2.0,除了如果令牌无效(上面的第 2 步)并且从未添加过声明,我会得到“未指定 authenticationScheme,并且没有找到 DefaultChallengeScheme。”

所以现在我正在阅读 2.0 中更改的身份验证:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x

我在 ASP.NET Core 2.0 中做同样事情的正确路径是什么?我没有看到进行真正自定义身份验证的示例。

【问题讨论】:

试试这个链接,虽然它说 2 个方案,但它会让你在 Authentication wildermuth.com/2017/08/19/… 上抬头 您可以添加您的代码以便我们查看吗?我知道我在 core2.0 中遇到了 JWT 的问题 - 是在启动时移动它的一个案例 【参考方案1】:

因此,经过一整天的尝试来解决这个问题,我终于弄明白了微软希望我们如何为他们在 core 2.0 中的新单中间件设置制作自定义身份验证处理程序。

在浏览了 MSDN 上的一些文档后,我发现了一个名为 AuthenticationHandler<TOption> 的类,它实现了 IAuthenticationHandler 接口。

从那里,我找到了一个完整的代码库,其中包含位于 https://github.com/aspnet/Security 的现有身份验证方案

在其中之一中,它显示了 Microsoft 如何实现 JwtBearer 身份验证方案。 (https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer)

我将大部分代码复制到一个新文件夹中,并清除了与 JwtBearer 相关的所有内容。

JwtBearerHandler 类(扩展AuthenticationHandler<>)中,有一个Task<AuthenticateResult> HandleAuthenticateAsync() 的覆盖

我在旧的中间件中添加了用于通过自定义令牌服务器设置声明,但仍然遇到一些权限问题,当令牌无效且没有声明时,我只是吐出 200 OK 而不是 401 Unauthorized设置。

我意识到我已经覆盖了Task HandleChallengeAsync(AuthenticationProperties properties),无论出于何种原因,它都被用于通过控制器中的[Authorize(Roles="")] 设置权限。

删除此覆盖后,代码运行正常,并且在权限不匹配时成功抛出了401

主要的收获是,现在您不能使用自定义中间件,您必须通过AuthenticationHandler<> 实现它,并且您必须在使用services.AddAuthentication(...) 时设置DefaultAuthenticateSchemeDefaultChallengeScheme

这是一个应该是什么样子的示例:

在 Startup.cs/ConfigureServices() 中添加:

services.AddAuthentication(options =>

    // the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...)
    options.DefaultAuthenticateScheme = "Custom Scheme";
    options.DefaultChallengeScheme = "Custom Scheme";
)
.AddCustomAuth(o =>  );

在 Startup.cs / Configure() 添加:

app.UseAuthentication();

创建一个新文件 CustomAuthExtensions.cs

public static class CustomAuthExtensions

    public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
    
        return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
    

新建文件CustomAuthOptions.cs

public class CustomAuthOptions: AuthenticationSchemeOptions

    public CustomAuthOptions()
    

    

新建文件CustomAuthHandler.cs

internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>

    public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    
        // store custom services here...
    
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    
        // build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package
        return AuthenticateResult.NoResult();
    

【讨论】:

很棒的帖子,但我在编译您的代码时遇到了一些问题。缺少 CustomAuthOptions 和 AuthenticateResult 类型。可以发一下吗? 你愿意在 Github repo 上用代码分享你的结论吗? 你能解释一下DefaultAuthenticateSchemeDefaultChallengeScheme吗?我不明白为什么它们都被使用?以及它们之间有什么区别。 +1 表示“从那里,我发现了一个完整的代码库,其中包含位于 github.com/aspnet/Security 的现有身份验证方案。”只需看看 ASP.NET 团队是如何按照这个(非常好的)答案进行操作的。我们有没有想过有一天我们会问有关 MS 代码和实践的问题,而答案会是,“看看他们的代码库?” 对于稍后加入的其他人,您的 AuthExtension 需要位于 Microsoft.Extensions.DependencyInjection 命名空间内。请参阅此示例:github.com/aspnet/Security/blob/rel/2.0.0/src/…【参考方案2】:

正如您引用的文章指出的那样,从 Core 1.x 到 Core 2.0 的 Identity 发生了相当大的变化。主要变化是摆脱中间件方法并使用依赖注入来配置自定义服务。这为更复杂的实现自定义身份提供了更大的灵活性。因此,您希望摆脱上面提到的中间件方法并转向服务。按照参考文章中的迁移步骤来实现此目标。首先将 app.UseIdentity 替换为 app.UseAuthenticationUseIdentity 已弃用,未来版本将不再支持。有关如何插入自定义声明转换并对声明 view this blog post 执行授权的完整示例。

【讨论】:

有没有关于如何将其与 WebAPI 应用程序一起使用的示例?

以上是关于ASP.NET Core 2.0 身份验证中间件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Asp.Net Core 2.0“AddJwtBearer”中间件中设置多个受众?

没有身份的 ASP.NET Core 2.0 承载身份验证

ASP.NET Core 2.0 - Windows Auth 与 LDAP 组到角色

如何在 ASP.NET Core 2.0 中设置多个身份验证方案?

如何在 ASP.NET Core 2.0 中根据路由配置服务身份验证

asp.net core 2.0 授权在身份验证(JWT)之前触发