ASP.NET 多个范围的核心 ClaimsAuthorizationRequirement 未按预期工作?
ASP.NET Core ClaimsAuthorizationRequirement for multiple scopes not working as intended?
我遇到了一些事情,如果这是有意为之的行为或主要的安全风险,想征求您的意见。
我打算做的是授权两个 API 具有不同策略的控制器操作。一个策略需要一个范围,另一个策略需要两个范围。
因此我定义了范围
- scope:1
- scope:2
我打算授权的控制器以及授权方式如下:
[ApiController]
[Route("api/v1/[controller]")]
//intentionally no authorize here
public class TestContoller : ControllerBase
{
[HttpGet("single")]
[Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(SingleScopePolicy))]
public IActionResult GetSingle() { return Ok("success"); }
[HttpGet("double")]
[Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(DoubleScopePolicy))]
public IActionResult GetDouble() { return Ok("success"); }
}
预期的行为(据我现在理解)是当 SingleScopePolicy 检测到它没有 scope:1 并且 DoubleScopePolicy 检测到它没有 scope:1 时 returns 禁止 ANDscope:2。 AND 是相关部分!
在 Startup.cs 中,我配置了授权并添加了类似的范围(故意没有用于测试的默认策略)
public void ConfigureService(IServiceCollection service)
{
// ...
services.AddAuthorization
(
options =>
{
options.AddPolicy(nameof(SingleScopePolicy), new SingleScopePolicy());
options.AddPolicy(nameof(DoubleScopePolicy), new DoubleScopePolicy());
}
);
// ...
}
我通过代码定义了我的两个策略:
public class SingleScopePolicy : AuthorizationPolicy
{
public SingleScopePolicy() : base
(
new IAuthorizationRequirement[]
{
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1 })
},
new string[] { "Bearer" }
) { }
}
public class DoubleScopePolicy : AuthorizationPolicy
{
public DoubleScopePolicy() : base
(
new IAuthorizationRequirement[]
{
// does not work (never returns forbid)
//new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" })
// works
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1" }),
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:2" }),
},
new string[] { "Bearer" }
) { }
}
我现在的问题是在 DoubleScopePolicy 中声明授权要求是否有效,或者是否有意使其无效。
实际上从不 returns 禁止使用下面的行,并且始终允许访问。这让我惊叹,因为它为您提供了一个字符串 [],我将其理解为 "hey, give me two and I will check there are both"。如果我在两行中单独定义它,它会按预期工作(由我)。
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" })
ClaimsAuthorizationRequirement
的 source 显示 AllowedValues
属性 被视为 或 操作:
found = context.User.Claims.Any(
c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)
&& requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal));
// ...
if (found)
{
context.Succeed(requirement);
}
如您所述,您可以添加多个 ClaimsAuthorizationRequirement
以便将检查视为 和 操作。
我遇到了一些事情,如果这是有意为之的行为或主要的安全风险,想征求您的意见。
我打算做的是授权两个 API 具有不同策略的控制器操作。一个策略需要一个范围,另一个策略需要两个范围。
因此我定义了范围
- scope:1
- scope:2
我打算授权的控制器以及授权方式如下:
[ApiController]
[Route("api/v1/[controller]")]
//intentionally no authorize here
public class TestContoller : ControllerBase
{
[HttpGet("single")]
[Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(SingleScopePolicy))]
public IActionResult GetSingle() { return Ok("success"); }
[HttpGet("double")]
[Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(DoubleScopePolicy))]
public IActionResult GetDouble() { return Ok("success"); }
}
预期的行为(据我现在理解)是当 SingleScopePolicy 检测到它没有 scope:1 并且 DoubleScopePolicy 检测到它没有 scope:1 时 returns 禁止 ANDscope:2。 AND 是相关部分!
在 Startup.cs 中,我配置了授权并添加了类似的范围(故意没有用于测试的默认策略)
public void ConfigureService(IServiceCollection service)
{
// ...
services.AddAuthorization
(
options =>
{
options.AddPolicy(nameof(SingleScopePolicy), new SingleScopePolicy());
options.AddPolicy(nameof(DoubleScopePolicy), new DoubleScopePolicy());
}
);
// ...
}
我通过代码定义了我的两个策略:
public class SingleScopePolicy : AuthorizationPolicy
{
public SingleScopePolicy() : base
(
new IAuthorizationRequirement[]
{
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1 })
},
new string[] { "Bearer" }
) { }
}
public class DoubleScopePolicy : AuthorizationPolicy
{
public DoubleScopePolicy() : base
(
new IAuthorizationRequirement[]
{
// does not work (never returns forbid)
//new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" })
// works
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1" }),
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:2" }),
},
new string[] { "Bearer" }
) { }
}
我现在的问题是在 DoubleScopePolicy 中声明授权要求是否有效,或者是否有意使其无效。
实际上从不 returns 禁止使用下面的行,并且始终允许访问。这让我惊叹,因为它为您提供了一个字符串 [],我将其理解为 "hey, give me two and I will check there are both"。如果我在两行中单独定义它,它会按预期工作(由我)。
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" })
ClaimsAuthorizationRequirement
的 source 显示 AllowedValues
属性 被视为 或 操作:
found = context.User.Claims.Any(
c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)
&& requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal));
// ...
if (found)
{
context.Succeed(requirement);
}
如您所述,您可以添加多个 ClaimsAuthorizationRequirement
以便将检查视为 和 操作。