在dotnet core 1.1 asp中,通过执行以下操作,我能够配置和使用身份中间件,然后使用jwt中间件:
app.UseIdentity();
app.UseJwtBearerAuthentication(new JwtBearerOptions() {});
现在已经改变了,因为我们使用以下方法实现中间件:
app.UseAuthentication();
通过Startup.cs的ConfigureServices部分完成设置配置。
在迁移文档中有一些使用授权模式的参考:
在2.0项目中,通过服务配置身份验证。每 身份验证方案在ConfigureServices方法中注册 Startup.cs。 UseIdentity方法将替换为UseAuthentication。
另外还有一个参考:
设置默认身份验证方案
在1.x中,AutomaticAuthenticate和AutomaticChallenge属性 旨在设置在单一认证方案上。有 没有好办法强制执行此操作。
在2.0中,这两个属性已经存在 作为单个AuthenticationOptions实例上的标志删除 已经移入基础AuthenticationOptions类。属性 可以在AddAuthentication方法调用中配置 Startup.cs的ConfigureServices方法:
或者,使用AddAuthentication的重载版本 设置多个属性的方法。在以下重载 方法示例,默认方案设置为 CookieAuthenticationDefaults.AuthenticationScheme。身份验证 也可以在您的个人中指定方案 [授权]属性或授权策略。
在dotnet core 2.0中是否仍然可以使用多个身份验证模式?我无法获得遵守JWT配置(“承载”架构)的策略,并且目前只有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控制器在这里:
它使用应用程序生成的API密钥来获取对数据的只读访问权限。您可以在此处找到使用该策略的控制器实现:
将数据库连接字符串更改为指向SQL Server,然后运行该应用程序。它会自动迁移数据库并配置管理员用户(support@arragro.com - ArragroPassword1!)。然后转到菜单栏中的“设置”选项卡,然后单击“配置JWT ReadOnly API密钥设置”以获取密钥。在邮递员中,通过配置新选项卡并使用以下地址将其设置为POST来获取jwt令牌:
http://localhost:5000/api/auth/readonly-token
提供标题:Content-Type:application / json
供应身体:
{
"apiKey": "the api token from the previous step"
}
在响应中复制令牌,然后在邮递员中使用以下内容:
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());
});
根据建议,这可以不使用自定义中间件。
答案 0 :(得分:22)
Asp.Net Core 2.0肯定支持多种身份验证方案。
您可以尝试在Authorize
属性中指定架构,而不是使用身份验证中间件进行黑客攻击:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
我试一试,它运作良好。假设您已添加Identity和JWT,如下所示:
services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
由于AddIdentity()
已将cookie身份验证设置为默认架构,因此我们必须在控制器的Authorize
属性中指定架构。目前,我不知道如何覆盖AddIdentity()
设置的默认架构,或者我们最好不要这样做。
解决方法是组建一个新类(您可以称之为JwtAuthorize),该类派生自Authorize
并且 Bearer 作为默认架构,因此您没有每次都指定它。
<强>更新强>
找到覆盖身份默认身份验证方案的方法!
而不是下线:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
使用下面的重载来设置默认架构:
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>....
更新2
如评论中所述,您可以通过将它们连接在一起来启用Identity和JWT身份验证。
[Authorize(AuthenticationSchemes = "Identity.Application" + "," + JwtBearerDefaults.AuthenticationScheme)]
答案 1 :(得分:14)
我用这个问题解决了在.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 =>....
在我基于这个问题的初始解决方案中,我没有注意到我的代码中的两个更改都是必需的。希望我可以节省一些人浪费的时间:)
答案 2 :(得分:0)
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"]))
};
});
答案 3 :(得分:0)
根据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)。