【问题标题】:Custom Authorization policy with multiple requirements not working when applied to controller action具有多个要求的自定义授权策略在应用于控制器操作时不起作用
【发布时间】:2020-11-04 23:02:57
【问题描述】:

我有一个 .NET Core 3 WebAPI,我想在其中使用基于策略的自定义授权,其中一个策略有多个要求。

我在Startup.ConfigureServices() 中添加了策略,并在 DI 中添加了MyCustomPolicyHandler

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>();
        
    });                
}

我使用本文档中的示例实现了MyCustomPolicyHandlerPolicy-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")] 属性应该在操作级别起作用。

知道为什么这不起作用吗?

谢谢。

【问题讨论】:

    标签: asp.net-core asp.net-core-webapi authorize-attribute


    【解决方案1】:

    因为MyCustomPolicyHandler注入的地方放错了。需要放在AddAuthorization之外。

    services.AddAuthorization(options =>
    {
         options.AddPolicy("MyCustomPolicy", policy =>
         {
             policy.Requirements.Add(new RequirementA());
             //...
         });          
    });
    
    services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
    

    结果:

    【讨论】:

    • 好收获!你介意告诉我你在哪里应用了策略(在控制器或操作中?)。不幸的是,我仍然显示pendingRequirements = 0
    • 我把政策放在行动上。
    猜你喜欢
    • 2017-03-04
    • 2016-04-07
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多