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

pbz*_*pbz 84 c# authentication asp.net-core asp.net-core-2.0

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

/sf/answers/2202565921/

它的工作方式如下:

  1. 中间件运行了.从请求标头中选取一个令牌.
  2. 验证了令牌,如果有效,则构建一个包含多个声明的身份(ClaimsIdentity),然后通过HttpContext.User.AddIdentity()添加;
  3. 在使用services.AddAuthorization的ConfigureServices中,我添加了一个策略来要求中间件提供的声明.
  4. 在控制器/操作中,我将使用[授权(角色="中间件添加的某些角色")]

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

所以现在我正在读取2.0中的auth更改:

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

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

小智 180

因此,经过漫长的一天尝试解决这个问题后,我终于想出了微软是如何让我们为核心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而不是a 401 Unauthorized.

我意识到我已经覆盖Task HandleChallengeAsync(AuthenticationProperties properties)了无论出于何种原因用于[Authorize(Roles="")]在控制器中设置权限.

删除此覆盖后,代码已经运行,并且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 => { });
Run Code Online (Sandbox Code Playgroud)

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

app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)

创建一个新文件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);
    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个新文件CustomAuthOptions.cs

public class CustomAuthOptions: AuthenticationSchemeOptions
{
    public CustomAuthOptions()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个新文件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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • "从那里,我找到了一个完整的代码库,其中现有的身份验证方案位于https://github.com/aspnet/Security." 只需看看ASP.NET团队如何按照这个(非常好的)答案进行操作.我们有没有人认为有一天我们会问MS代码和实践的问题,答案是"只是看看他们的代码库?" (10认同)
  • 你愿意在Github回购的代码中分享你的结论吗? (8认同)
  • 对于稍后进入的其他人,你的`AuthExtension`需要在`Microsoft.Extensions.DependencyInjection`命名空间内.请参阅此示例:https://github.com/aspnet/Security/blob/rel/2.0.0/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs#L8 (3认同)
  • 你能解释一下`DefaultAuthenticateScheme`和`DefaultChallengeScheme`吗?我不明白他们为什么都用过?他们之间有什么区别. (2认同)

Kev*_*ans 6

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

  • 有关于如何将其与 WebAPI 应用程序一起使用的示例吗? (12认同)