.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"
}
})
我们有标准的 .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"
}
})