c# - ASP.NET Core 2.0 认证中间件

标签 c# authentication asp.net-core asp.net-core-2.0

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

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

它是这样工作的:

  1. 中间件运行。从请求 header 中获取 token 。
  2. 验证 token ,如果有效,则构建一个包含多个声明的身份 (ClaimsIdentity),然后通过 HttpContext.User.AddIdentity() 添加这些声明;
  3. 在使用 services.AddAuthorization 的 ConfigureServices 中,我添加了一个策略来要求中间件提供的声明。
  4. 然后在 Controller /操作中我会使用 [Authorize(Roles = "中间件添加的某些角色")]

这在某种程度上适用于 2.0,但如果 token 无效(上面的第 2 步)并且从未添加声明,我会得到“没有指定 authenticationScheme,并且没有找到 DefaultChallengeScheme。”

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

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

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

最佳答案

因此,在尝试解决这个问题一整天之后,我终于弄明白了 Microsoft 希望我们如何为他们在核心 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()

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

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

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

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

下面是这一切应该是什么样子的示例:

在 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();
    }
}

关于c# - ASP.NET Core 2.0 认证中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45805411/

相关文章:

C# - 为什么 System.IO.File.GetLastAccessTime 在找不到文件时返回预期值?

c# - 哪个 Linux 发行版最适合在虚拟机中开发 Mono 应用程序?

node.js - NodeJS - 使用 Active Directory 进行身份验证

mysql - SabreDav 身份验证失败

asp.net-core - 对 nginx 反向代理背后的应用程序进行故障排除,因为 POST/PUT 请求回复错误 400(错误请求)

c# - 如何从单例中使用 Scoped 服务?

c# - 使用委托(delegate)异步调用方法是最佳实践吗?

c# - 如何在 C# 中使用 Console.Log、Print_R()、Debug.Trace?

c++ - mongodb C++ 驱动验证

sql-server - 如何使 FileStream 文件可供 Web 应用程序使用