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

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

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

它像这样工作:

  • 中间件跑了。 从请求标头中提取一个令牌。
  • 验证令牌,如果有效,则构建包含多个声明然后通过HttpContext.User.AddIdentity()添加的标识(ClaimsIdentity);
  • 在使用services.AddAuthorization的ConfigureServices中,我添加了一个策略来要求中间件提供的声明。
  • 在控制器/操作中,我将使用[授权(角色=“中间件添加的某个角色”)]
  • 这有点适用于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.0中的新的单一中间件设置制作自定义身份验证处理程序。

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

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

    其中之一,它显示了Microsoft如何实现JwtBearer身份验证方案。 (https://github.com/aspnet/Security/tree/dev/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();
        }
    }
    

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

    链接地址: http://www.djcxy.com/p/22349.html

    上一篇: ASP.NET Core 2.0 authentication middleware

    下一篇: Dotnet core security oauth and bearer