【问题标题】:How to create a custom Authorize attribute for multiple policies in ASP.NET CORE如何在 ASP.NET CORE 中为多个策略创建自定义授权属性
【发布时间】:2018-12-05 07:52:28
【问题描述】:

我想授权一个动作控制器可以通过多个策略访问。

.例如:

[Authorize([Policies.ManageAllCalculationPolicy,Policies.ManageAllPriceListPolicy]]
public async Task<IActionResult> Get(int id){}

非常感谢。

【问题讨论】:

  • 恕我直言,只需添加第三条策略...

标签: c# asp.net-core authorization asp.net-core-webapi


【解决方案1】:

对于多个策略,您可以实现自己的 AuthorizeAttribute。

  • AuthorizeMultiplePolicyAttribute

     public class AuthorizeMultiplePolicyAttribute:TypeFilterAttribute
     {
     public AuthorizeMultiplePolicyAttribute(string policies,bool IsAll):base(typeof(AuthorizeMultiplePolicyFilter))
     {
         Arguments = new object[] { policies,IsAll};
     }
     }
    
  • AuthorizeMultiplePolicyFilter

     public class AuthorizeMultiplePolicyFilter: IAsyncAuthorizationFilter
     {
     private readonly IAuthorizationService _authorization;
     public string _policies { get; private set; }
     public bool _isAll { get; set; }
     public AuthorizeMultiplePolicyFilter(string policies, bool IsAll,IAuthorizationService authorization)
     {
         _policies = policies;
         _authorization = authorization;
         _isAll = IsAll;
     }
    
     public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
     {
    
         var policys = _policies.Split(";").ToList();
         if (_isAll)
         {
             foreach (var policy in policys)
             {
                 var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
                 if (!authorized.Succeeded)
                 {
                     context.Result = new ForbidResult();
                     return;
                 }
             }
         }
         else
         {
             foreach (var policy in policys)
             {
                 var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
                 if (authorized.Succeeded)
                 {
                     return;
                 }
             }
             context.Result = new ForbidResult();
             return;
         }
     }
     }
    
  • 在启动时添加所需的策略

     services.AddAuthorization(options =>
         {
    
             options.AddPolicy("ManageAllCalculationPolicy", policy =>
                     policy.RequireAssertion(context =>
                         context.User.HasClaim(c => c.Type == "BadgeId")));
    
             options.AddPolicy("ManageAllPriceListPolicy", policy =>
                     policy.RequireAssertion(context =>
                         context.User.HasClaim(c => c.Type == "aaaa")));
         });
    
  • 基于其中一项政策的授权

     [AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", false)]
    
  • 基于所有政策的授权

     [AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", true)]
    

【讨论】:

  • 我在这段代码中使用了这个; context.Result = new RedirectToActionResult("Index", "Error", new { code = 403 });并且工作得很好,感谢您的付出
  • 如果你想使用 AND 你可以只使用两个 Authorize 属性。 [Authorize("ManageAllCalculationPolicy")] [Authorize("ManageAllPriceListPolicy")]
【解决方案2】:

不,您不能将多个策略添加为条件为or 的列表。我认为 NetCore 不支持。

尝试创建新策略。

services.AddAuthorization(options =>
{
    options.AddPolicy("BadgeEntry", policy =>
        policy.RequireAssertion(context =>
            context.User.HasClaim(c =>
                (c.Type == ClaimTypes.BadgeId ||
                 c.Type == ClaimTypes.TemporaryBadgeId) &&
                 c.Issuer == "https://microsoftsecurity")));
});

参考:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1#why-would-i-want-multiple-handlers-for-a-requirement

【讨论】:

    【解决方案3】:

    您可以添加多个类似的策略

    services.AddAuthorization(options =>
    {
        options.AddPolicy("BadgeEntry", PolicyClaimCheck.Any, new string[2] { "VT102","RS102" });
        options.AddPolicy("Notification", PolicyClaimCheck.All, new string[2] { "XTX101","NT102" });
    });
    

    如果有一个就足够了,你应该使用PolicyClaimCheck.Any或者如果必须拥有所有,你应该使用PolicyClaimCheck.All

    【讨论】:

    • 这是哪个 .NET 版本? PolciyClaimCheck 在 .net core 3.1 中不可用
    【解决方案4】:

    工作就像一个魅力!!

    这是我在 Startup.ConfigureServices 中的部分代码

    services.AddAuthorization(config =>
                    {
                        config.AddPolicy(Policies.Admin, Policies.AdminPolicy());
                        config.AddPolicy(Policies.Register, Policies.RegistradorPolicy());
                    });
    

    例如,政策是:

    public class Policies
    {
            public const string Admin = 'Admin';
            public const string Register = 'Register';
    
            public static AuthorizationPolicy AdminPolicy()
            {
                return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().RequireRole(Admin).Build();
            }
    
            public static AuthorizationPolicy RegisterPolicy()
            {
                return new AuthorizationPolicyBuilder().RequireAuthenticatedUser().RequireRole(Register).Build();
            }
    
    }
    

    然后在控制器中..

    [HttpGet]
            [AuthorizeMultiplePolicy(Policies.Admin + ";" + Policies.Register, false)]
            public ActionResult<IEnumerable<Accion>> GetAll(){
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多