我有两个JWT,它们包含在对我的服务的所有调用中。第一个(称为UserJwt
(是我希望用于大多数服务操作的[Authorize]
。第二个(称为ApplicationJwt
(具有有用的信息,我也希望这些信息位于ClaimsIdentity
对象的User.Identities
列表中。
我设置我的代码,以便始终使用UserJwt
,而忽略ApplicationJwt
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
// Setup the JWT stuff here for the UserJwt
})
这很好,但我希望解析这两个JWT并将其放入User.Identities
列表中。
我尝试将代码设置为遵循此答案(针对问题:使用多个JWT承载身份验证(,但这允许任一(UserJwt
或ApplicationJwt
(。
在最坏的情况下,我需要它来同时要求两者。然而,我更希望它只需要UserJwt
,但如果找到ApplicationJwt
,则将其作为ClaimsIdentity
。
services.AddAuthentication()
.AddJwtBearer("UserJwt", options =>
{
// Setup the JWT stuff here for the UserJwt
})
.AddJwtBearer("ApplicationJwt", options =>
{
// Setup the JWT stuff here for the ApplicationJwt
});
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("UserJwt", "ApplicationJwt")
.Build();
});
如何让两个JWT都在User.Identities
列表中,让UserJwt是用于[Authorize]
的JWT,但也允许[Authorize(Policy = "ApplicationJwt")]
执行某些服务操作
这里的一个选项是将自定义需求添加到默认策略中。
假设UserJwt包含特定声明:
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("UserJwt", "ApplicationJwt")
.RequireAuthenticatedUser()
.AddRequirements(
// Assume UserJwt contains a AuthenticationMethod claim where
// value is equal to User
new ClaimsAuthorizationRequirement(
ClaimTypes.AuthenticationMethod, new[] { "User" }
)
)
.Build();
另请参阅其他内置需求类型。
请注意,当不满足要求时,用户仍然通过身份验证,但被拒绝访问。要处理禁用场景,请使用JwtBearerEvents.OnForbidden
事件:
OnForbidden = async context =>
{
context.Response.StatusCode = 401;
}