Sujit.Warrier
Sujit.Warrier

Reputation: 2869

Dynamic authorization of roles asp.net core

This is not a duplicate question or rather the solutions given in other solutions have not worked.

Lets say there is a controller

[Authorize(Roles=//set dynamically)]
public IActionResult DashBoard(LoginModel model)
{
}

I have tried the solutions in the following questions

  1. Add roles to authorize attribute

  2. dynamically assign controller action permissions to roles

  3. dynamically add roles to authorize attribute for controller (Error: Handle method - no suitable method found to override )

  4. can policy based authorization be more dynamic

All of these solutions do not work as either the methods overridden in the interfaces are not present (eg. authorizeAttribute does not contain a definition for AuthorizeCore) or in some cases IServiceCollection services does not contain a particular method

Upvotes: 15

Views: 25835

Answers (3)

Mehdi Nabizadeh
Mehdi Nabizadeh

Reputation: 24

i think you have to use Policy instead if role for authorization. in fact one of the benefit of the policy based vs role based is this.

Upvotes: 0

Prathimanan
Prathimanan

Reputation: 1

public IActionResult Validate(LoginDetails userobj)
       {
          LoginDetails user = new LoginDetails();
         var checklogin = from s in appDbContext.loginDetails where s.UserName == userobj.UserName && s.Password == userobj.Password select s;

               if (checklogin != null && checklogin.Count() > 0)
               {
                   if (checklogin.FirstOrDefault().Role == 1)
                   {
                       return RedirectToAction("Home");
                   }
                   else if (checklogin.FirstOrDefault().Role == 2)
                   {
                       var UserId = checklogin.FirstOrDefault().LoginId;
                       HttpContext.Session.SetInt32("UserId", UserId);
                       return RedirectToAction("Index1");
                   } 
           }

           return RedirectToAction("Failed");
       }

Upvotes: -7

Tseng
Tseng

Reputation: 64150

You can't do that. [Authorize(Roles=//set dynamically)] must be know at compile time. Also using roles for this very reason is discouraged as pointed in blowdart's linked post from comments.

Instead, you should use claims and policies. Claims are fine grained permissions, for example "CreateCustomer" or "DeleteCustomer" or "ViewDashboard".

So you have to use it like

[Authorize(Policy = "ViewDashboard")]

These policies need to be know at compile time.

public class ViewDashboardRequirement : AuthorizationHandler<ViewDashboardRequirement>, IAuthorizationRequirement
{
    public override void Handle(AuthorizationContext context, ViewDashboardRequirement requirement)
    {
        if (context.User.HasClaim(c => c.Type == "dashboard:read"))
        {
            context.context.Succeed(requirement);
            return;
        }

        // only call fail if you do not want that other AuthorizationHandler may succeed with 
        // a different requirement
        // context.Fail();
    }
}

For an example on how to generate a generic handler (instead of writing a new Handler for each policy) see my answer here.

This will allow you to create configurable roles. Now you can create roles which consists as a bag of claims. Each claim may be one policies. When the user logs in, you add the claims that belong to a role to the list of users claims.

i.e.

  • Support: ViewDashboard, ViewCustomers, ViewContacts, ManageCases (support tickets)
  • Manager: ViewDashboard, ManageCustomers (View, Edit, Delete), ManageContacts (View, Edit, Delete)
  • Administrator: ManageDashboard (View, Edit)

etc.

Update from Comments.

You should be able to utilize ASP.NET Core Identity's claim and roleclaim abilities w/o changing a line of code, therefor you have the IdentityRole and IdentityRoleClaim classes. At runtime, you add a new IdentityRole (i.e. "Manager") and then add multiple IdentityRoleClaim (one for each permission/policy)

Upvotes: 20

Related Questions