Role Based Authorization
15 Jun 2020 | CSharp-ASP.NET CoreWhen users register on your website, you may want to distribute their different roles. For example, the user Ellen has comedian and citizen roles, and user LiWenliang has a whistleblower role. Different Roles have different permissions. In this article, I will show you how to implements a role-based authorization step by step.
Adding Roles
Multiple ways can achieve adding roles for a user. You can add it through a claim or an identity.
var userClaim = new List<Claim>()
{
new Claim(ClaimTypes.Name, "user name"),
new Claim(ClaimTypes.Role,"admin")
};
or add roles by UserManager
(if you are using identity authorization):
//if the role doesn't exist,create it
if (!await _roleManager.RoleExistsAsync("admin"))
{
await _roleManager.CreateAsync(new IdentityRole("admin"));
}
//add the role to the current user
await _userManager.AddToRoleAsync(user,"admin");
The _roleManager
is an instance of the type RoleManager<IdentityRole>
, and the _userManager
is an instance of the type UserManager<IdentityUser>
. Both instances inject via Constructor injection.
As UserManger
and RoleManager
are under in the Microsoft.AspNetCore.Identity namespace, so you needs to install the Microsoft.AspNetCore.Identity.EntityFrameworkCore
package, and the UserManager
and RoleManager
will automatically map actions into the database by Entity Framework Core.
Checking Roles
You can use authorize
attribute with the role
parameter to authority a user’s roles. You can embed them against actions or controllers.
[Authorize(Roles = "admin")]
public IActionResult SecretAction() {
}
[Authorize(Roles = "admin")]
public class SecretController : Controller{
}
You can specify multiple roles as a comma separated list:
[Authorize(Roles = "admin,guest")]
public class SecretController : Controller
{
}
This controller would be only accessible by users who are members of the admin
role or the guest
role.
If you apply multiple attributes then an accessing user must be a member of all the roles specified; the following sample requires that a user must be a member of both the citizen
and president
role.
[Authorize(Roles = "citizen")]
[Authorize(Roles = "president")]
public class WhiteHouseController : Controller
{
}
You can also lock down a controller but allow anonymous, unauthenticated access to individual actions.
[Authorize(Role = "admin")]
public class TestController : Controller
{
public ActionResult Action1()
{
}
[AllowAnonymous]
public ActionResult Action2()
{
}
}
Policy based role checks
Role requirements can also be expressed using the new Policy syntax, where a developer registers a policy at startup
as part of the Authorization
service configuration. This normally occurs in ConfigureServices()
in your Startup.cs
file.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdministratorRole",
policy => policy.RequireRole("Administrator"));
});
}
Policies are applied using the Policy
property on the AuthorizeAttribute
attribute:
[Authorize(Policy = "RequireAdministratorRole")]
public IActionResult Secret()
{
return View();
}
Getting Roles
You can use the following method to retrieve out all roles of a user.
//get a ClaimsPrincipal instance
ClaimsPrincipal _claimsPrincipal = HttpContext.User;
//all roles that user belongs to
List<String> roles = _claimsPrincipal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(s=>s.Value).ToList();
//check is if user has a specify role
if (_claimsPrincipal.IsInRole("admin")) {
}
If you are working on identity authorization, then check the following code:
var user = await _userManager.GetUserAsync(User);
IList<String> roles = await _userManager.GetRolesAsync(user);
//.. more operations
You can found this project’s respository in authentication and authroization github respository.
Comments