Vinicius Bassi
Vinicius Bassi

Reputation: 504

How to check if a User is in a single role? Using Identity in .NET Core 3.1

How do I check if the current user is in a single role?

In my app I can have an user with multiple roles, but, some roles like Role1, have specific behaviors. How do I isolate the specific behavior from Role1 when a user have two roles(Role1 and Role2)? If the user is in Role2 then they should have another behavior, even if they are in Role1 as well.

The solution I came up with was

if (User.IsInRole(Role1.ToString()) && !User.IsInRole(Role2.ToString()))
{
   //implementation
}

Is there another way to do this? Maybe using policies?

Upvotes: 1

Views: 3141

Answers (3)

Vinicius Bassi
Vinicius Bassi

Reputation: 504

The solution for me was creating a method that check if the user was in any of the roles:

    public async Task<bool> IsInAnyRoleAsync(TUser user, RoleEnum[] roles)
    {
        var userIsInRole = new List<bool>();
        foreach (var role in roles)
        {
            var roleName = Enum.GetName(role.GetType(), role);
            userIsInRole.Add(await IsInRoleAsync(user, roleName));
        }

        return userIsInRole.Any(isInRole => isInRole == true);
    }

Upvotes: 0

Zhi Lv
Zhi Lv

Reputation: 21726

How do I check if the current user is in a single role?

After user login successfully, you could use the UserManager.GetRoleAsync() method to get a list of role names the specified user belongs to. Then, based on the result to check whether the user is in a single Role.

            var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                var user = _userManager.FindByEmailAsync(Input.Email).Result;
                var roles = _userManager.GetRolesAsync(user).Result.ToArray();
                // then, based on the roles array to check if the current user is in a single role.

                _logger.LogInformation("User logged in.");
                return LocalRedirect(returnUrl);
            }

The screenshot as below:

enter image description here

How do I isolate the specific behavior from Role1 when a user have two roles(Role1 and Role2)? If the user is in Role2 then they should have another behavior, even if they are in Role1 as well. Is there another way to do this? Maybe using policies?

Yes, Policy-based authorization is a good choice. For example, in my sample, there have 3 kinds of Roles: Admin, Manager and User.

We could create the following policies in the Startup.cs file,

        services.AddAuthorization(options => {
            options.AddPolicy("readpolicy",
                builder => builder.RequireRole("Admin", "Manager", "User"));
            options.AddPolicy("writepolicy",
                builder => builder.RequireRole("Admin", "Manager"));
        });

Then, we will apply these policies to the Role controller, as below:

    [Authorize(Policy = "readpolicy")]
    public IActionResult Index()
    {
        var roles = roleManager.Roles.ToList();
        return View(roles);
    }
    [Authorize(Policy = "writepolicy")]
    public IActionResult Create()
    {
        return View(new IdentityRole());
    }

Now, we can based on the policy to call the action method.

Reference:

Adding Role Authorization to a ASP.NET MVC Core Application

Policy-based authorization in ASP.NET Core

Upvotes: 3

Pedro Costa
Pedro Costa

Reputation: 194

I guess a policy it is the best aproach to your case. Create a policy that uses RequireAssertion in builder

Se this post: Role based authorization in ASP.NET Core 3.1 with Identity and ExternalLogin

Upvotes: 0

Related Questions