你完全可以实现你想要的:
services
.AddAuthentication()
.AddJwtBearer("Firebase", options =>
{
options.Authority = "https://securetoken.google.com/my-firebase-project";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "my-firebase-project",
ValidateAudience = true,
ValidAudience = "my-firebase-project",
ValidateLifetime = true
};
})
.AddJwtBearer("Custom", options =>
{
});
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
});
让我们来看看你的代码和那个代码之间的区别。
AddAuthentication
没有参数
如果您设置了默认的身份验证方案,则在每个请求上,身份验证中间件将尝试运行与默认身份验证方案关联的身份验证处理程序。由于现在有两种可能的身份验证方案,因此运行其中一种方案是没有意义的。
使用另一个重载的AddJwtBearer
每个AddXXX
方法添加身份验证都有几个重载:
现在,因为您两次使用了相同的身份验证方法,但身份验证方案必须是唯一的,所以您需要使用第二个重载。
更新默认策略
由于请求不再自动进行身份验证,因此在某些操作上放置[Authorize]
属性将导致请求被拒绝并发出HTTP 401
。
由于这不是我们想要的,因为我们希望授权处理程序有机会对请求进行身份验证,所以我们通过指示应尝试使用Firebase
和Custom
身份验证方案来对授权系统的默认策略进行更改,以对请求进行身份验证。
这并不会阻止您在某些操作上更加严格;[Authorize]
属性具有AuthenticationSchemes
属性,允许您覆盖哪些身份验证方案是有效的。
如果您有更复杂的场景,可以利用基于策略的授权。我发现官方文档非常好。
假设某些操作仅适用于由Firebase发行的JWT令牌,并且必须具有特定值的声明;您可以按以下方式执行:
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase")
.RequireClaim("role", "admin")
.Build());
});
您可以在某些操作上使用[Authorize(Policy = "FirebaseAdministrators")]
。
最后需要注意的一点是:如果您捕获AuthenticationFailed
事件并且使用除第一个AddJwtBearer
策略以外的任何内容,您可能会看到IDX10501: Signature validation failed. Unable to match key...
。这是由于系统逐个检查每个AddJwtBearer
直到找到匹配项。通常可以忽略此错误。
更新 - .net core 6
对于较新版本的.net core,您需要指定默认授权,因此.AddAuthentication()
将不起作用。
例如:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Audience = "https://localhost:5000/";
options.Authority = "https://localhost:5000/identity/";
})
.AddJwtBearer("AzureAD", options =>
{
options.Audience = "https://localhost:5000/";
options.Authority = "https://login.microsoftonline.com/eb971100-7f436/";
});
builder.Services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme,
"AzureAD");
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
请查看https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-6.0#use-multiple-authentication-schemes以获取更多信息。