如何在 ASP.NET CORE 中为多个策略创建自定义授权属性

Pho*_*ong 8 c# authorization asp.net-core asp.net-core-webapi

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

。例如:

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

非常感谢。

Xue*_*hen 13

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

  • AuthorizeMultiplePolicyAttribute

     public class AuthorizeMultiplePolicyAttribute:TypeFilterAttribute
     {
     public AuthorizeMultiplePolicyAttribute(string policies,bool IsAll):base(typeof(AuthorizeMultiplePolicyFilter))
     {
         Arguments = new object[] { policies,IsAll};
     }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  • 授权多重策略过滤器

     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;
         }
     }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  • 在启动时添加您想要的策略

     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")));
         });
    
    Run Code Online (Sandbox Code Playgroud)
  • 基于其中一项政策的授权

     [AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", false)]
    
    Run Code Online (Sandbox Code Playgroud)
  • 基于所有策略的授权

     [AuthorizeMultiplePolicy("ManageAllCalculationPolicy;ManageAllPriceListPolicy", true)]
    
    Run Code Online (Sandbox Code Playgroud)

  • 如果您想使用 AND,则只需使用两个 Authorize 属性即可。[授权(“管理所有计算政策”)] [授权(“管理所有价格列表政策”)] (3认同)

Kha*_*yen 3

不可以,您不能将多个策略添加为具有条件的列表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")));
});
Run Code Online (Sandbox Code Playgroud)

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