我碰到了一些东西,想问问您这是否是故意的行为或重大的安全风险。
我打算做的是用不同的策略授权两个API控制器操作。一种策略需要一个范围,另一种策略需要两个范围。
为此,我定义了范围
我打算授权的控制器及其执行方式如下:
[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检测到它不具有范围:1并且DoubleScopePolicy检测到它不具有范围:1 AND 范围: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" })
答案 0 :(得分:2)
ClaimsAuthorizationRequirement
的{{3}}表明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
以便将检查视为和操作。