Reputation: 504
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
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
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:
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
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