23

Net Core policy authorization, however it is looking very static to me. Because in the Enterprise Application, there is an often need for new roles which will need new policies (as far as i understand) or if you want to implement new type of policy specific for certain client. For example if we are building an CMS which will be driven by those policies, we will want, each client to be able to define hes own. So can this new policy base mechanism be more dynamic or, it's idea is entire different?

thanks :))

Petar Minev
  • 418
  • 1
  • 4
  • 10
  • Before asked following question i was thinking like you. (http://stackoverflow.com/questions/36445780/how-to-implement-permission-based-access-control-with-asp-net-core). But @Tseng's answer changed my mind. The answer shows that `policy authorization` can be used dynamically. Take a look at the answer, it might be useful for your case. – adem caglin May 16 '16 at 07:57
  • You shouldn't use "roles" anymore (as used in ASP.NET 4.5 / MVC 5 before), use claims instead. Roles aren't very flexible and require that you change your code every time you add a new role. A claim is a specific permission based on a feature of your application, i.e. "ReadArticle" or "WriteArticle", "DeleteArticle", "CreateUser" etc. This way you only need to add a policy, when you add a new feature (like ability to manage users or post articles). A "role would be simply just a collection of claims that a user has when he logs in. Then check it in the policy – Tseng May 16 '16 at 09:46
  • 1
    Just keep in mind, you can't create a dynamic policy when there wasn't one before. I.e. you can't allow user to specify a "over age of 18" policy, if there is no code in the backend which handles it (i.e. `AgeOver18` policy and handler that checks the age of the user). So a policy can't be created by a non-developer or someone who doesn't have access to the source code (since you are required to add checks to this specific policy in the code). Rather than creating a new policy, you create a role a collection of existing policies / permissions. – Tseng May 16 '16 at 09:55

2 Answers2

28

I always recommend that people take a look @ the least privilege repo as it has some great examples of all the various approaches one can take with the new ASP.NET Core Authentication and Authorization paradigms.

Can this new policy base mechanism be more dynamic?

Yes, in fact it is more dynamic than the previous role based concepts. It allows for you to define policies that can be data driven. Here is another great resource for details pertaining to this. You can specify that an API entry point for example is protected by a policy (for example), and that policy can have a handler and that handler can do anything it needs to, i.e.; examine the current User in context, compare claims to values in the database, compare roles, anything really. Consider the following:

Define an entry point with the Policy

[Authorize(Policy = "DataDrivenExample")]
public IActionResult GetFooBar()
{
    // Omitted for brevity...
}

Add the authorization with the options that add the policy.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();    
    services.AddAuthorization(options =>
    {
        options.AddPolicy("DataDrivenExample",
                          policy => 
                          policy.Requirements.Add(new DataDrivenRequirement()));
    });    
    services.AddSingleton<IAuthorizationHandler, DataDrivenHandler>();
}

Then define the handler.

public class MinimumAgeHandler : AuthorizationHandler<DataDrivenRequirement>
{
    protected override void Handle(AuthorizationContext context, 
                                   DataDrivenRequirement requirement)
    {
        // Do anything here, interact with DB, User, claims, Roles, etc.
        // As long as you set either:
        //    context.Succeed(requirement);
        //    context.Fail();
    }
}

Is the idea entirely different?

It should feel very similar to the previous concepts that you're accustomed to with auth8 and authz.

David Pine
  • 21,735
  • 6
  • 69
  • 98
  • Thank you this is really everything that i needed to know :))) – Petar Minev May 16 '16 at 14:03
  • How about the minimal age changed from 21 to 18 at some point in time? How do the authorization change accordingly? does it have to restart the server? – liang Apr 02 '18 at 08:52
  • It depends, if it is a `static` check yes - the web server would have to restart. However, if it is dynamically retrieved from a database or an `IOptionsSnapshot` each time - then no. – David Pine Apr 03 '18 at 12:37
  • I am interested in whether I should store all permissions from database as a Claim and then write my handler to check the Claim? Or should I just go to the database and lookup whether the user has the permission? I want to avoid going to the database as much as possible but I also do not want to introduce security flaws. I've thought about loading all permissions as claims and storing them in a cookie as well. Any help would be appreciated. – Zach Painter Jul 02 '19 at 17:19
  • Hi @ZachPainter, I'd suggest asking a new question and referencing this one. – David Pine Jul 02 '19 at 19:56
  • Is it possible to have variable like [Authorize(Policy = "DataDrivenExample", var1=1, var2="bli")] ? – Tito Nov 14 '19 at 15:56
  • 1
    So with this approach we need to create handler and add in services for each permission ? Isn't there more generic solution ? – Tigran Petrosyan Apr 19 '21 at 15:08
12

The accepted answer is still quite limiting. It doesn't allow for dynamic values at the Controller and Action level. The only place a custom value could be added is in the requirement when the policy is added. Sometimes you need more fine grain control over the authorization process. A very common scenario is permission based security. Each controller and action should be able to specify the permissions required to access them. See my answer here for a more powerful solution that lets you use custom attributes to decorate your controllers and actions with any information you need while doing authorization.

Community
  • 1
  • 1
Shawn
  • 661
  • 8
  • 9