.NET [Authorize] - 使用 JWT Body "Role" 以外的路径

.NET [Authorize] - Use JWT Body Path Other than "Role"

我们有标准的 .NET Core [Authorize(Roles = "Foo")] authorization attributes.

它们在 Startup.cs 中设置,以通过 JWT 在授权 header 中以标准 out-of-the-box 方式检查角色,例如:

.AddJwtBearer(jwtBearerOptions => {...}

我们当前的令牌如下所示,并且运行良好:

{
  "role": "Foo",
  "exp": 1937249412,
}

我们的新令牌将类似于下面的令牌。我们无法控制传入的令牌(但有对称密钥):

{
  "www.bar.com/role": "Foo",
  "exp": 1937249412,
}

核心问题:有没有办法改变[Authorize]www.bar.com/role而不是在JWTRole中寻找令牌body,默认情况下是什么?

P.S。我知道我可以添加中间件来将 Role 写入令牌并 re-sign 写入令牌。我也知道我可以写 [CustomAuthorize] 属性或使用 policy-based 身份验证。感觉应该有一种简单的方法来做这么简单的事情,而不必弄乱传入的请求或替换整个应用程序中的 [Authorize] 属性。

想到的第一个解决方案

您可以通过策略播放它并在后台使用角色。这是一个例子。在您的控制器中:

[Authorize(Policy = "Foo")]
public Whatever() {}

然后像这样注册您的保单:

services.AddAuthorization(options =>
{
    options.AddPolicy("Foo", policy => policy.RequireClaim("www.bar.com/role", new[] { "Foo" }));
}

即您的“Foo”策略要求用户为声明“www.bar.com/role”.

设置值“Foo”

深入挖掘来源

事实上,如果您添加具有角色的 Authorize 属性,则不会像上面的策略示例那样在后台发生更多事情。 .net 使用 RolesAuthorizationRequirement 创建授权策略,此要求通过调用 context.User.IsInRole 来检查角色,后者又调用 ClaimsIdentity 上的 HasClaim(_identities[i].RoleClaimType, role)RoleClaimType 在 .net ClaimsIdentity 中默认设置为“roles/”。

所以另一种方法可能是拦截 ClaimsIdentity 的创建并使用另一个具有“roleType”参数的构造函数调用它,它允许覆盖默认角色声明名称。

一个可能更好的解决方案

所以我查找了 ClaimsIdentity 并找到了 this docu。看来你可以通过令牌验证参数来获取它:

services.AddAuthentication()
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        RoleClaimType = "www.bar.com/role"
    }
})