.Net Core Web API, Authorize a Action if Either of Role OR Policy Matches

Viewed 867

I have developed the Rest APIs using .Net Core and my API is consumed by two sources, one from the UI and another from the services.

For Authorizing UI, i have used JWToken approach with claims, where as for Services I have used Role based Integrated security authorization.

i.e., for UI, i need to provide [Authorize(Policy="XYZ")] where as for Services, I need to provide [Authorize(Role="ABC")]

Most of my apis are either used by UI or services dedicatedly, but there are few APIs which can be used by both UI and Services, but facing, hence for such APIs, i need to provide a condition like either Role or Policy matches,

Eg., Authorize[Role="ABC", Policy="XYZ"] , but this statement expects both Role and policy to be available with AND Condition, but i need to solution to implement the same with kind of OR condition. Please help me if anyone has encountered this type of scenario.

FYI, I have tried using Custom Attributes, but it is not working out, because I have custom attributes independently created for Roles (Using AuthorizeAttribute) and for Policies (Using TypeFilterAttribute and IAsyncAuthorizationFilter), but again I am not able to combine the same with OR condition

1 Answers

To implement OR condition ,you could use custom Authorize attribute which accepts Role and Policy as arguments.Return 403 if neither of them is matched.

Below is a simple demo:

1.Create a AuthorizeMultiplePolicyAttribute class

public class AuthorizeMultiplePolicyAttribute : TypeFilterAttribute
{
    public AuthorizeMultiplePolicyAttribute(string role, string policy) : base(typeof(AuthorizeMultiplePolicyFilter))
    {
        Arguments = new object[] { role, policy };
    }
}

2.Create AuthorizeMultiplePolicyFilter

public class AuthorizeMultiplePolicyFilter : IAsyncAuthorizationFilter
{
    private readonly IAuthorizationService _authorization;
    public string _role { get; private set; }
    public string _policy { get; private set; }

    public AuthorizeMultiplePolicyFilter(string role, string policy, IAuthorizationService authorization)
    {
        _role = role;
        _policy = policy;
        _authorization = authorization;

    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var policyAuthorized = await _authorization.AuthorizeAsync(context.HttpContext.User, _policy);
        var roleAuthorized = context.HttpContext.User.IsInRole(_role);

        if(!policyAuthorized.Succeeded && !roleAuthorized)
        {
            context.Result = new ForbidResult();
            return;
        }

    }
}

3.Use the custom attribute

[AuthorizeMultiplePolicy("Admin","XYZ")]

For multiple roles/policies, you could refer to How to create a custom Authorize attribute for multiple policies in ASP.NET CORE

Related