Home > Software design >  .Net core Authorize attribute inheritance of roles from global to controller
.Net core Authorize attribute inheritance of roles from global to controller

Time:06-11

As I understand, there are 3 'levels' that I can use the authorise attribute with roles in my web application. The first would be global auth policy for the webapp, like the following:

serviceCollection.AddMvcCore(options =>
            {
                options.Filters.Add(new AuthorizeFilter("MyPolicy"));
            })
            .AddAuthorization(options =>
            {
                options.AddPolicy("MyPolicy", builder =>
                {
                    builder.RequireAuthenticatedUser();
                    builder.RequireRole(new[]{"MyRole1","MyRole2"});
                });
            });

This would mean that only logged in users with MyRole1 or MyRole2 could use the webapp.

The next two levels would be using an authorisation attribute at the controller level and then at the endpoint level as shown here:

[Authorize(Roles = "MyRole3,MyRole4")]
public class MyController : Controller
{
    public MyController(){}

    [HttpGet]
    [Authorize(Roles = "MyRole5,MyRole6")]
    public async Task<IActionResult> Get()
    {
        var result = "something";
        return this.OkOrBadRequest(result);
    }
  }

In this case which roles apply to the endpoint? Are all the roles ORed together all the way down, are all the roles ANDed together all the way down, or is it the case of "most specific first"?

In the case of ORing together all the way down this would mean that any role from MyRole1 to MyRole6 could access the Get endpoint here.

In the case of ANDing together all the way down this would mean that a user needs (MyRole1 OR MyRole2) AND (MyRole3 OR MyRole4) AND (MyRole5 OR MyRole6) to access the Get endpoint here.

In the case of "most specific first" it would mean that only MyRole5 or MyRole6 could access the endpoint and roles at all other levels are ignored.

What would I do if I want to add an AND at a particular level, for example on MyController I want it to be (MyRole3 || MyRole4) && MyRole7?

CodePudding user response:

The authorize attributes are ANDed together. So you should read the Authorization chain as MyRole1 OR MyRole2 AND MyRole3 OR MyRole4 AND MyRole5 OR MyRole6. From this you should be able to determine how the action will be accessed.

(MyRole1 || MyRole2) && (MyRole3 || MyRole4) && (MyRole5 || MyRole6)

this implies that to access the method you need at least one role from each group.

  • Related