Dotnet核心2.0认证多个模式身份cookie和jwt

did*_*man 28 asp.net authentication jwt asp.net-identity .net-core

在dotnet core 1.1 asp中,通过执行以下操作,我能够配置和使用身份中间件,然后使用jwt中间件:

  app.UseIdentity();
  app.UseJwtBearerAuthentication(new JwtBearerOptions() {});
Run Code Online (Sandbox Code Playgroud)

现在已经改变了,我们实现了中间件:

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

通过Startup.cs的ConfigureServices部分完成设置的配置.

在迁移文档中有一些使用授权模式的参考:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x#authentication-middleware-and-services

在2.0项目中,身份验证是通过服务配置的.每个身份验证方案都在Startup.cs的ConfigureServices方法中注册.UseIdentity方法替换为UseAuthentication.

另外还有一个参考:

设置默认身份验证方案

在1.x中,AutomaticAuthenticate和AutomaticChallenge属性旨在在单个身份验证方案上设置.没有好办法强制执行此操作.

在2.0中,这两个属性已作为单个AuthenticationOptions实例上的标志删除,并已移至基本AuthenticationOptions类中.可以在Startup.cs的ConfigureServices方法中的AddAuthentication方法调用中配置属性:

或者,使用AddAuthentication方法的重载版本来设置多个属性.在以下重载方法示例中,默认方案设置为CookieAuthenticationDefaults.AuthenticationScheme.或者,可以在您的[授权]属性或授权策略中指定身份验证方案.

在dotnet core 2.0中仍然可以使用多个身份验证模式吗?我无法使策略尊重JWT配置("承载"架构),并且只有Identity在配置时才正在工作.我找不到任何多个身份验证模式的示例.

编辑:

我重读了文档,现在明白了:

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

为默认架构添加自动身份验证.Identity为您配置默认架构.

通过在Startup.cs配置中执行以下操作,我已经解决了看起来像黑客攻击新api的问题:

    app.UseAuthentication();
    app.Use(async (context, next) =>
    {
        if (!context.User.Identity.IsAuthenticated)
        {
            var result = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
            if (result?.Principal != null)
            {
                context.User = result.Principal;
            }
        }

        await next.Invoke();
    });
Run Code Online (Sandbox Code Playgroud)

这是正确的方法,还是我应该利用框架,DI和接口来实现IAuthenticationSchemeProvider的自定义实现?

编辑 - 实施的详细信息以及在何处找到它.

可以在此处找到JWT配置,我使用策略来定义授权,其中包括已接受的身份验证架构:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Management/Startup.cs

自定义中间件仍然实现.Auth控制器在这里:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/AuthController.cs

它使用应用程序生成的API密钥来获取对数据的只读访问权限.您可以在此处找到使用策略的控制器实现:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/SitemapController.cs

将数据库连接字符串更改为指向SQL Server,然后运行该应用程序.它会自动迁移数据库并配置管理员用户(support@arragro.com - ArragroPassword1!).然后转到菜单栏中的"设置"选项卡,然后单击"配置JWT ReadOnly API密钥设置"以获取密钥.在邮递员中,通过配置新选项卡并使用以下地址将其设置为POST来获取jwt令牌:

HTTP://本地主机:5000/API/auth /中只读令牌

提供标题:Content-Type:application/json

供应身体:

{
    "apiKey": "the api token from the previous step"
}
Run Code Online (Sandbox Code Playgroud)

复制响应中的令牌,然后在邮递员中使用以下内容:

HTTP://本地主机:5000/API /网站导航/平

Authorization: "bearer - The token you received in the previous request"
Run Code Online (Sandbox Code Playgroud)

由于自定义中间件,它将初始工作.注释掉上面提到的代码,然后再试一次,你将获得401.

编辑 - @ DonnyTian的答案在他的评论中涵盖了我的解决方案.我遇到的问题是在UseMvc上设置默认策略,但没有提供架构:

    services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });
Run Code Online (Sandbox Code Playgroud)

根据建议,这没有自定义中间件.

Don*_*ian 23

Asp.Net Core 2.0绝对支持多种身份验证方案.您可以尝试在Authorize属性中指定架构,而不是使用身份验证中间件进行黑客攻击:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Run Code Online (Sandbox Code Playgroud)

我尝试了一下,它工作正常.假设您已添加Identity和JWT,如下所示:

services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Run Code Online (Sandbox Code Playgroud)

由于AddIdentity()已将cookie身份验证设置为默认架构,因此我们必须在Authorize控制器的属性中指定架构.目前,我不知道如何覆盖默认架构AddIdentity(),或者我们最好不要这样做.

一个解决办法是编写一个新的类,从派生(也可以称之为JwtAuthorize) Authorize,并有承载作为默认模式,这样你就不必每次都指定它.

UPDATE

找到了覆盖Identity默认身份验证方案的方法!

而不是下线:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Run Code Online (Sandbox Code Playgroud)

使用下面的重载来设置默认架构:

services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....
Run Code Online (Sandbox Code Playgroud)

更新2 如评论中所述,您可以通过将它们连接在一起来启用Identity和JWT身份验证. [Authorize(AuthenticationSchemes = "Identity.Application" + "," + JwtBearerDefaults.AuthenticationScheme)]

  • 只想指出您上面没有提到的内容。Authorize属性中的AuthenticationSchemes属性接受以逗号分隔的身份验证方案名称列表。像[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme +“,” + CookieAuthenticationDefaults.AuthenticationScheme)] (2认同)

Mar*_*inH 14

我使用这个问题来解决在.Net Core 2.0 Web应用程序中将Identity和Bearer身份验证相结合的(类似)问题.需要注意的重要一点是,您需要添加new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme以下代码:

services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });
Run Code Online (Sandbox Code Playgroud)

添加默认身份验证选项:

services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....
Run Code Online (Sandbox Code Playgroud)

在我基于这个问题的初始解决方案中,我没有注意到我的代码中的两个更改都是必需的.希望我可以节省一些人浪费的时间:)

  • 哇!这不是饼干,而是身份……非常感谢! (2认同)