具有多个要求的自定义授权策略在应用于控制器操作时不起作用
Custom Authorization policy with multiple requirements not working when applied to controller action
我有一个 .NET Core 3 WebAPI,我想在其中使用基于策略的自定义授权,其中一个策略有多个要求。
我已经在 Startup.ConfigureServices()
中添加了策略,并将 MyCustomPolicyHandler
添加到 DI:
public virtual void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
policy.Requirements.Add(new RequirementB());
policy.Requirements.Add(new RequirementC());
policy.Requirements.Add(new RequirementD());
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
});
}
我已经使用此文档中的示例实现了 MyCustomPolicyHandler
:
Policy-based authorization in ASP.NET Core
public class MyCustomPolicyHandler: IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();
Console.WriteLine($"MyCustomPolicyHandler: {pendingRequirements.Count} requirements");
foreach (var requirement in pendingRequirements)
{
if(requirement is RequirementA) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementB) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementC) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementD) {
// do stuff to check the requirements
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
接下来,我将策略应用于控制器操作之一:
public class MyController
{
[HttpGet]
[Authorize(Policy="MyCustomPolicy")]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
我遇到的问题是没有与政策相关的要求。 Console.WriteLine()
消息显示 0 个要求:
MyCustomPolicyHandler: 0 requirements
如果我将策略移动到控制器,则存在要求:
[Authorize(Policy="MyCustomPolicy")]
public class MyController
{
[HttpGet]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
MyCustomPolicyHandler: 4 requirements
但是,我需要将此策略应用于操作,而不是控制器。 [Authorize(Policy="MyCustomPolicy")] 属性应在操作级别起作用。
知道为什么这不起作用吗?
谢谢。
因为MyCustomPolicyHandler
注入的地方放错了。需要放在AddAuthorization
.
之外
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
//...
});
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
结果:
我有一个 .NET Core 3 WebAPI,我想在其中使用基于策略的自定义授权,其中一个策略有多个要求。
我已经在 Startup.ConfigureServices()
中添加了策略,并将 MyCustomPolicyHandler
添加到 DI:
public virtual void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
policy.Requirements.Add(new RequirementB());
policy.Requirements.Add(new RequirementC());
policy.Requirements.Add(new RequirementD());
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
});
}
我已经使用此文档中的示例实现了 MyCustomPolicyHandler
:
Policy-based authorization in ASP.NET Core
public class MyCustomPolicyHandler: IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();
Console.WriteLine($"MyCustomPolicyHandler: {pendingRequirements.Count} requirements");
foreach (var requirement in pendingRequirements)
{
if(requirement is RequirementA) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementB) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementC) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementD) {
// do stuff to check the requirements
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
接下来,我将策略应用于控制器操作之一:
public class MyController
{
[HttpGet]
[Authorize(Policy="MyCustomPolicy")]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
我遇到的问题是没有与政策相关的要求。 Console.WriteLine()
消息显示 0 个要求:
MyCustomPolicyHandler: 0 requirements
如果我将策略移动到控制器,则存在要求:
[Authorize(Policy="MyCustomPolicy")]
public class MyController
{
[HttpGet]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
MyCustomPolicyHandler: 4 requirements
但是,我需要将此策略应用于操作,而不是控制器。 [Authorize(Policy="MyCustomPolicy")] 属性应在操作级别起作用。
知道为什么这不起作用吗?
谢谢。
因为MyCustomPolicyHandler
注入的地方放错了。需要放在AddAuthorization
.
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
//...
});
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
结果: