如何为ASP.NET CORE中的多个策略创建自定义Authorize属性

时间:2018-12-05 07:52:29

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

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

,例如:

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

非常感谢。

4 个答案:

答案 0 :(得分:1)

否,您不能将多个策略添加为条件为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

答案 1 :(得分: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)]
    

答案 2 :(得分:0)

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

<Link route="/register/location">
  <button className="btn btn-basic btn-sm" type="button" onClick={() => { }}>
    <span>Sign Up</span>
  </button>
</Link>

如果拥有一个就足够了,则应使用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

答案 3 :(得分:0)

像魅力一样工作!

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

eval

例如,政策是:

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

}