2

I have a controller that authorizes logged in users based on roles.

now we have a generic website that allows users from different companies to login, how do I dynamically restrict the controllers based on roles.

Here is my code

[Authorize(Roles = "CompanyA")]   ///how can I dyanmicaly set the Roles e.g CompanyB, CompanyC etc
public ActionResult Index()
{
  your code
}

UPDATE BASED ON @MISHA130 Advise

Problem now is how to I get the authenticated user and which roles he/she has ? thanks

public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            // Go to the database, check your user role compare if the user can do it.
            // do all your logic here
           

            var xx = HttpContext.User.Identity.Name;
            var a = User.Identity.GetUserId();
            var x = HttpContext.Current.User.Identity.Name;
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); // will give the user's userId
            var userNames = User.FindFirstValue(ClaimTypes.Name); // will give the user's userName


            string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            isAuthorized = await _userManager.IsInRoleAsync(userName, "RSA Test");
            if (!isAuthorized)
            {
                context.Result = new ForbidResult();
            }
        }
Ehioze
  • 39
  • 1
  • 4

1 Answers1

0

You can add an authorization filter and do your own logic there:

public class DynamicRoleFilterAttribute : Attribute, IAsyncAuthorizationFilter
{
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        // Go to the database, check your user role compare if the user can do it.
        // do all your logic here

        if (!isAuthorized)
        {
            context.Result = new ForbidResult();
        }
    }
}

Afterwards apply it to your actions as need be

[DynamicRoleFilter]
public ActionResult Index()
{
   // your code
}

Or you can globally add it to all your actions by adding it in your Startup.cs:

services.AddControllers(options =>
                options.Filters.Add<DynamicRoleFilterAttribute >())
misha130
  • 5,457
  • 2
  • 29
  • 51
  • thanks @misha130 , problem now is that I cant test the code, as I cant get the current logged in user or which role the user has ? I have updated my code – Ehioze Dec 12 '21 at 11:40
  • You mean in integration you aren't actually authenticated so you can't test the code? Well authenticate, send a login request before your normal request or mock the MvcOptions so it won't have the new filter or inject mvcoptions and remove the filter. But this is a different question to your original – misha130 Dec 12 '21 at 12:11
  • My question is how do I go to the database to get either the roles or claims. I tried var abc = _userManager.GetRolesAsync(); var claims = _userManager.GetClaimsAsync(); as the class OnAuthorizationAsync( does not provide any overloads to pass the userID to it ??? – Ehioze Dec 12 '21 at 13:39
  • Oh, save the roles of the users in the actual database then inject a service to the attribute and get the list from the actual database and compare it to what is the actual current role – misha130 Dec 12 '21 at 13:58