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



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

app.UseIdentity();
app.UseJwtBearerAuthentication(new JwtBearerOptions() {});

现在这种情况已经改变了,我们用实现中间件

app.UseAuthentication();

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

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

https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x#authentication-中间件和服务

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

此外还有一个参考:

设置默认身份验证方案

在1.x中,AutomaticAuthenticate和AutomaticChallenge属性旨在设置在单个身份验证方案上。有没有好的方法来强制执行这一点。

在2.0中,这两个属性作为单个AuthenticationOptions实例上的标志删除,并且已移动到基本AuthenticationOptions类中。属性可以在ConfigureServices Startup.cs:方法

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

在dotnet core 2.0中仍然可以使用多个身份验证模式吗?我无法获得尊重JWT配置("Bearer"模式)的策略,并且目前只有Identity在两者都配置的情况下工作。我找不到任何多个身份验证模式的示例。

编辑:

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

app.UseAuthentication()

添加了针对默认模式的自动身份验证。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();
});

这是正确的方法吗?还是我应该利用框架、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

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

http://localhost:5000/api/auth/readonly-代币

提供标题:内容类型:application/json

供应车身:

{
"apiKey": "the api token from the previous step"
}

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

http://localhost:5000/api/sitemap/flat

Authorization: "bearer - The token you received in the previous request"

由于有了自定义中间件,它将开始工作。注释掉上面提到的代码,然后重试,您将收到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());
});

根据建议,这在没有自定义中间件的情况下也能工作。

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

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

我试了一下,效果很好。假设您添加了Identity和JWT,如下所示:

services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

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

解决方法是编写一个从Authorize派生的新类(可以称之为JwtAuthorize),并将Bearer作为默认模式,因此不必每次都指定它。

更新

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

而不是下面的行:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

使用以下重载设置默认架构:

services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>....

UPDATE 2如注释中所述,您可以通过将Identity和JWT auth连接在一起来启用它们。 [Authorize(AuthenticationSchemes = "Identity.Application" + "," + JwtBearerDefaults.AuthenticationScheme)]

我用这个问题来解决在中组合身份验证和承载身份验证的(类似)问题。Net Core 2.0 web应用程序。需要注意的是,您需要将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());
});

添加默认身份验证选项:

services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>....

在基于这个问题的最初解决方案中,我没有注意到需要对代码进行这两项更改。希望我能为某人节省我浪费的时间:)

基于kevin rich在这里所说的http://www.whoiskevinrich.com/configuring-asp-net-core-2-0-authentication

我可以将jwt设置为默认的身份验证方法:

services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
})

我对此进行了测试,并能够从donnytian的帖子中提到的authorize属性中删除(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)。

Sean Wildermuth发表了一篇关于启用cookie和jwt的博客文章:https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2

他把它锁成这样:

services.AddAuthentication()
.AddCookie(cfg => cfg.SlidingExpiration = true)
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});

关于注释'[Authorize(AuthenticationSchemes="Identity.Application"+","+JwtBearerDefaults.AuthenticationScheme)]'

这是一个常量,也是JwtBearerDefaults的正确值。身份验证方案是"承载">

[授权(AuthenticationSchemes="{命名您的方案},Bearer)]

必须始终放置常量的值,而不是其名称。

相关内容

  • 没有找到相关文章

最新更新