我遇到了一些问题,想问您一些建议,如果这是故意的行为或重大的安全风险。
我打算做的是用不同的策略授权两个API控制器操作。一个策略需要一个范围,另一策略需要两个范围。
为此,我定义了范围
范围:1
范围: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和scope: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工作中要求授权要求,还是打算不起作用。
使用下面的行实际上从不禁止返回,并且始终允许访问。这种方式令我感到惊讶,因为它为您提供了一个string [],我会理解为“嘿,给我两个,然后我会检查两个都存在”。如果我在两行中分别定义它,则按我的预期工作。
new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" })
最佳答案
ClaimsAuthorizationRequirement
的source显示AllowedValues
属性被视为or操作:
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
以便将检查视为and操作。关于c# - 多个作用域的ASP.NET Core ClaimsAuthorizationRequirement是否无法按预期工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56055649/