您可以完全实现您想要的:
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
依次检查每个事件直到获得匹配项引起的。该错误通常可以忽略。