app.UseIdentity(); app.UseJwtBearerAuthentication(new JwtBearerOptions() {});
现在这已经发生了变化,我们实现了中间件:
app.UseAuthentication();
通过Startup.cs的ConfigureServices部分完成设置的配置。
在迁移文档中有一些使用授权模式的参考:
In 2.0 projects,authentication is configured via services. Each
authentication scheme is registered in the ConfigureServices method of
Startup.cs. The UseIdentity method is replaced with UseAuthentication.
另外还有一个参考:
Setting Default Authentication Schemes
In 1.x,the AutomaticAuthenticate and AutomaticChallenge properties
were intended to be set on a single authentication scheme. There was
no good way to enforce this.In 2.0,these two properties have been
removed as flags on the individual AuthenticationOptions instance and
have moved into the base AuthenticationOptions class. The properties
can be configured in the AddAuthentication method call within the
ConfigureServices method of Startup.cs:Alternatively,use an overloaded version of the AddAuthentication
method to set more than one property. In the following overloaded
method example,the default scheme is set to
CookieAuthenticationDefaults.AuthenticationScheme. The authentication
scheme may alternatively be specified within your individual
[Authorize] attributes or authorization policies.
在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()); });
根据建议,这没有自定义中间件。
解决方法
您可以尝试在Authorize属性中指定架构,而不是使用身份验证中间件进行黑客攻击:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
我试了一下,它工作得很好。假设您已添加Identity和JWT,如下所示:
services.AddIdentity<ApplicationUser,ApplicationRole>() services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
由于AddIdentity()已将cookie身份验证设置为默认架构,因此我们必须在控制器的Authorize属性中指定架构。目前,我不知道如何覆盖AddIdentity()设置的默认模式,或者我们最好不要这样做。
解决方法是组建一个新类(您可以称之为JwtAuthorize),该类派生自Authorize并将Bearer作为默认模式,因此您不必每次都指定它。
UPDATE
找到了覆盖Identity默认身份验证方案的方法!
而不是下线:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
使用下面的重载来设置默认架构:
services.AddAuthentication(option => { option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options =>....
更新2
如评论中所述,您可以通过将它们连接在一起来启用Identity和JWT身份验证。
[授权(AuthenticationSchemes =“Identity.Application”“,”JwtBearerDefaults.AuthenticationScheme)]