你完全可以实现你想要的:
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 =>
{
// Configuration for your custom
// JWT tokens here
});
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
});
让我们来看看你的代码和那个代码之间的区别。
AddAuthentication 没有参数
如果您设置默认身份验证方案,那么在每个请求中,身份验证中间件都将尝试运行与默认身份验证方案关联的身份验证处理程序。由于我们现在有两个可行的身份验证方案,因此运行其中一个是没有意义的。
使用 AddJwtBearer 的另一个重载
添加身份验证的每个 AddXXX 方法都有几个重载:
使用与身份验证方法关联的默认身份验证方案的一种,您可以在此处看到 cookie 身份验证
除了选项的配置之外,您还可以传递身份验证方案的名称,就像在这个重载中一样
现在,因为您使用了两次相同的身份验证方法,但身份验证方案必须是唯一的,所以您需要使用第二次重载。
更新默认策略
由于请求将不再自动进行身份验证,因此将 [Authorize] 属性添加到某些操作将导致请求被拒绝并发出 HTTP 401。
因为这不是我们想要的,因为我们想让身份验证处理程序有机会对请求进行身份验证,所以我们更改了授权系统的默认策略,指示应尝试使用 Firebase 和自定义身份验证方案来对请求进行身份验证。
这并不妨碍您对某些操作更加严格; [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")]。