I am using the ASP.NET Core default website template and have the authentication selected as "Individual User Accounts". How can I create roles and assign it to users so that I can use the roles in a controller to filter access?
-
do you know to to identify user roles during login? – Yirga Dec 19 '17 at 13:08
9 Answers
My comment was deleted because I provided a link to a similar question I answered here. Ergo, I'll answer it more descriptively this time. Here goes.
You could do this easily by creating a CreateRoles
method in your startup
class. This helps check if the roles are created, and creates the roles if they aren't; on application startup. Like so.
private async Task CreateRoles(IServiceProvider serviceProvider)
{
//initializing custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
string[] roleNames = { "Admin", "Manager", "Member" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
//create the roles and seed them to the database: Question 1
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
//Here you could create a super user who will maintain the web app
var poweruser = new ApplicationUser
{
UserName = Configuration["AppSettings:UserName"],
Email = Configuration["AppSettings:UserEmail"],
};
//Ensure you have these values in your appsettings.json file
string userPWD = Configuration["AppSettings:UserPassword"];
var _user = await UserManager.FindByEmailAsync(Configuration["AppSettings:AdminUserEmail"]);
if(_user == null)
{
var createPowerUser = await UserManager.CreateAsync(poweruser, userPWD);
if (createPowerUser.Succeeded)
{
//here we tie the new user to the role
await UserManager.AddToRoleAsync(poweruser, "Admin");
}
}
}
and then you could call the CreateRoles(serviceProvider).Wait();
method from the Configure
method in the Startup class.
ensure you have IServiceProvider
as a parameter in the Configure
class.
Using role-based authorization in a controller to filter user access: Question 2
You can do this easily, like so.
[Authorize(Roles="Manager")]
public class ManageController : Controller
{
//....
}
You can also use role-based authorization in the action method like so. Assign multiple roles, if you will
[Authorize(Roles="Admin, Manager")]
public IActionResult Index()
{
/*
.....
*/
}
While this works fine, for a much better practice, you might want to read about using policy based role checks. You can find it on the ASP.NET core documentation here, or this article I wrote about it here

- 2,350
- 1
- 14
- 14
-
2While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/15347488) – Jean-François Fabre Feb 26 '17 at 20:34
-
3Thanks Jean. I included the essential parts of the code in the answer and have provided links for reference, as suggested. – Temi Lajumoke Feb 28 '17 at 10:29
-
now that's beginning to look good. +1 (because you don't deserve a -1 now) – Jean-François Fabre Feb 28 '17 at 10:33
-
1In the new ApplicationUser part, would it be better to add EmailConfirmed = true ? – egmfrs May 30 '18 at 16:03
-
I am using asp.net core 2.1 and the first line of code throws this error : "One or more errors occurred. (No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.)" . Why it doesn't work as it should here ? – mahmoud fathy Aug 02 '18 at 16:51
-
11@mahmoudfathy Add `services.AddDefaultIdentity
().AddRoles – Dennis de Laat Nov 08 '18 at 20:24().AddEntityFrameworkStores ();` to your `ConfigureServices` -
1@TemiLajumoke I get an error Unable to resolve service for type 'System.IServiceProvider' while attempting to activate 'Test.Startup'.' – Tania Marinova Nov 05 '19 at 08:53
I have created an action in the Accounts
controller that calls a function to create the roles and assign the Admin
role to the default user. (You should probably remove the default user in production):
private async Task CreateRolesandUsers()
{
bool x = await _roleManager.RoleExistsAsync("Admin");
if (!x)
{
// first we create Admin rool
var role = new IdentityRole();
role.Name = "Admin";
await _roleManager.CreateAsync(role);
//Here we create a Admin super user who will maintain the website
var user = new ApplicationUser();
user.UserName = "default";
user.Email = "default@default.com";
string userPWD = "somepassword";
IdentityResult chkUser = await _userManager.CreateAsync(user, userPWD);
//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = await _userManager.AddToRoleAsync(user, "Admin");
}
}
// creating Creating Manager role
x = await _roleManager.RoleExistsAsync("Manager");
if (!x)
{
var role = new IdentityRole();
role.Name = "Manager";
await _roleManager.CreateAsync(role);
}
// creating Creating Employee role
x = await _roleManager.RoleExistsAsync("Employee");
if (!x)
{
var role = new IdentityRole();
role.Name = "Employee";
await _roleManager.CreateAsync(role);
}
}
After you could create a controller to manage roles for the users.

- 4,359
- 2
- 22
- 44

- 934
- 8
- 8
-
How can I get list of all the user having roles , I want to revoke roles and edit associated roles how can I do that ? – Bipn Paul Feb 28 '17 at 12:15
-
1@BipnPaul For that you can use the usermanager: `_userManager.GetUsersInRoleAsync("admin");` – Stephane Duteriez Feb 28 '17 at 16:04
-
this great but how to you assign these roles to users during registration and identify users role during login? please help am stuck at this? – Yirga Dec 19 '17 at 12:58
-
1I started a full job programming with js, so I put my test with asp.net on old. But when you create a new user, you should call "addToRoleAsync" with the new user. To controls the right of the user you should use methode like describe below [Authorize("admin")]. – Stephane Duteriez Dec 23 '17 at 08:54
-
4
-
-
1
-
Can't get it working. Any chance of showing the declaration and injection of _roleManager? – niico Mar 30 '21 at 12:19
Temi's answer is nearly correct, but you cannot call an asynchronous function from a non asynchronous function like he is suggesting. What you need to do is make asynchronous calls in a synchronous function like so :
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
CreateRoles(serviceProvider);
}
private void CreateRoles(IServiceProvider serviceProvider)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
Task<IdentityResult> roleResult;
string email = "someone@somewhere.com";
//Check that there is an Administrator role and create if not
Task<bool> hasAdminRole = roleManager.RoleExistsAsync("Administrator");
hasAdminRole.Wait();
if (!hasAdminRole.Result)
{
roleResult = roleManager.CreateAsync(new IdentityRole("Administrator"));
roleResult.Wait();
}
//Check if the admin user exists and create it if not
//Add to the Administrator role
Task<ApplicationUser> testUser = userManager.FindByEmailAsync(email);
testUser.Wait();
if (testUser.Result == null)
{
ApplicationUser administrator = new ApplicationUser();
administrator.Email = email;
administrator.UserName = email;
Task<IdentityResult> newUser = userManager.CreateAsync(administrator, "_AStrongP@ssword!");
newUser.Wait();
if (newUser.Result.Succeeded)
{
Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(administrator, "Administrator");
newUserRole.Wait();
}
}
}
The key to this is the use of the Task<> class and forcing the system to wait in a slightly different way in a synchronous way.

- 321
- 4
- 4
-
-
Actually i think this is one of the best answers, BUT, i would not use those UGLY Task
hasAdminRole = roleManager.RoleExistsAsync("Administrator"); and use instead var adminRoleExist = roleManager.RoleExistsAsync("Administrator").Result; Also i dislike the fact that an email is hardcoded, move the second part to the register controller, and if no admin exist the user get automatically added to the admin role... – L.Trabacchin Aug 31 '19 at 10:09 -
2Why not put this in the Program where the Main can be Async and we use the Roles configuration as a IWebHost extension. This seems to be suggested by some Microsofties (the extensions, not the main async): https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/april/data-points-ef-core-in-a-docker-containerized-app – Paulo Neves Dec 08 '19 at 13:56
I use this (DI):
public class IdentitySeed
{
private readonly ApplicationDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _rolesManager;
private readonly ILogger _logger;
public IdentitySeed(
ApplicationDbContext context,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
ILoggerFactory loggerFactory) {
_context = context;
_userManager = userManager;
_rolesManager = roleManager;
_logger = loggerFactory.CreateLogger<IdentitySeed>();
}
public async Task CreateRoles() {
if (await _context.Roles.AnyAsync()) {// not waste time
_logger.LogInformation("Exists Roles.");
return;
}
var adminRole = "Admin";
var roleNames = new String[] { adminRole, "Manager", "Crew", "Guest", "Designer" };
foreach (var roleName in roleNames) {
var role = await _rolesManager.RoleExistsAsync(roleName);
if (!role) {
var result = await _rolesManager.CreateAsync(new ApplicationRole { Name = roleName });
//
_logger.LogInformation("Create {0}: {1}", roleName, result.Succeeded);
}
}
// administrator
var user = new ApplicationUser {
UserName = "Administrator",
Email = "something@something.com",
EmailConfirmed = true
};
var i = await _userManager.FindByEmailAsync(user.Email);
if (i == null) {
var adminUser = await _userManager.CreateAsync(user, "Something*");
if (adminUser.Succeeded) {
await _userManager.AddToRoleAsync(user, adminRole);
//
_logger.LogInformation("Create {0}", user.UserName);
}
}
}
//! By: Luis Harvey Triana Vega
}

- 3,245
- 30
- 22
-
1ApplicationRole insted of IdentityRole because of i configure Identity primary key as GUID (https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-primary-key-configuration?tabs=aspnetcore2x) – Sith2021 Dec 13 '17 at 00:32
-
1
The following code will work ISA.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,
IServiceProvider serviceProvider)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
CreateRolesAndAdminUser(serviceProvider);
}
private static void CreateRolesAndAdminUser(IServiceProvider serviceProvider)
{
const string adminRoleName = "Administrator";
string[] roleNames = { adminRoleName, "Manager", "Member" };
foreach (string roleName in roleNames)
{
CreateRole(serviceProvider, roleName);
}
// Get these value from "appsettings.json" file.
string adminUserEmail = "someone22@somewhere.com";
string adminPwd = "_AStrongP1@ssword!";
AddUserToRole(serviceProvider, adminUserEmail, adminPwd, adminRoleName);
}
/// <summary>
/// Create a role if not exists.
/// </summary>
/// <param name="serviceProvider">Service Provider</param>
/// <param name="roleName">Role Name</param>
private static void CreateRole(IServiceProvider serviceProvider, string roleName)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
Task<bool> roleExists = roleManager.RoleExistsAsync(roleName);
roleExists.Wait();
if (!roleExists.Result)
{
Task<IdentityResult> roleResult = roleManager.CreateAsync(new IdentityRole(roleName));
roleResult.Wait();
}
}
/// <summary>
/// Add user to a role if the user exists, otherwise, create the user and adds him to the role.
/// </summary>
/// <param name="serviceProvider">Service Provider</param>
/// <param name="userEmail">User Email</param>
/// <param name="userPwd">User Password. Used to create the user if not exists.</param>
/// <param name="roleName">Role Name</param>
private static void AddUserToRole(IServiceProvider serviceProvider, string userEmail,
string userPwd, string roleName)
{
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
Task<ApplicationUser> checkAppUser = userManager.FindByEmailAsync(userEmail);
checkAppUser.Wait();
ApplicationUser appUser = checkAppUser.Result;
if (checkAppUser.Result == null)
{
ApplicationUser newAppUser = new ApplicationUser
{
Email = userEmail,
UserName = userEmail
};
Task<IdentityResult> taskCreateAppUser = userManager.CreateAsync(newAppUser, userPwd);
taskCreateAppUser.Wait();
if (taskCreateAppUser.Result.Succeeded)
{
appUser = newAppUser;
}
}
Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(appUser, roleName);
newUserRole.Wait();
}

- 3,688
- 2
- 27
- 25
In Configure method declare your role manager (Startup)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, RoleManager<IdentityRole> roleManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Task.Run(()=>this.CreateRoles(roleManager)).Wait();
}
private async Task CreateRoles(RoleManager<IdentityRole> roleManager)
{
foreach (string rol in this.Configuration.GetSection("Roles").Get<List<string>>())
{
if (!await roleManager.RoleExistsAsync(rol))
{
await roleManager.CreateAsync(new IdentityRole(rol));
}
}
}
OPTIONAL - In appsettings.JSON (it depends on you where you wanna get roles from)
{
"Roles": [
"SuperAdmin",
"Admin",
"Employee",
"Customer"
]
}

- 111
- 1
- 4
In addition to Temi Lajumoke's answer, it's worth noting that after creating the required roles and assigning them to specific users in ASP.NET Core 2.1 MVC Web Application, after launching the application, you may encounter a method error, such as registering or managing an account:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UI.Services.IEmailSender' while attempting to activate 'WebApplication.Areas.Identity.Pages.Account.Manage.IndexModel'.
A similar error can be quickly corrected in the ConfigureServices method by adding the AddDefaultUI() method:
services.AddIdentity<IdentityUser, IdentityRole>()
//services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
Check
https://blogs.msdn.microsoft.com/webdev/2018/03/02/aspnetcore-2-1-identity-ui/
and related topic on github:
https://github.com/aspnet/Docs/issues/6784 for more information.
And for assigning role to specific user could be used IdentityUser class instead of ApplicationUser.

- 3,638
- 5
- 27
- 47

- 367
- 4
- 9
.net 6 option:
public static class WebApplicationExtensions
{
public static async Task<WebApplication> CreateRolesAsync(this WebApplication app, IConfiguration configuration)
{
using var scope = app.Services.CreateScope();
var roleManager = (RoleManager<IdentityRole>)scope.ServiceProvider.GetService(typeof(RoleManager<IdentityRole>));
var roles = configuration.GetSection("Roles").Get<List<string>>();
foreach (var role in roles)
{
if (!await roleManager.RoleExistsAsync(role))
await roleManager.CreateAsync(new IdentityRole(role));
}
return app;
}
}
In Program.cs add before app.Run()
await app.CreateRolesAsync(builder.Configuration);

- 63
- 1
- 6
Update in 2020. Here is another way if you prefer.
IdentityResult res = new IdentityResult();
var _role = new IdentityRole();
_role.Name = role.RoleName;
res = await _roleManager.CreateAsync(_role);
if (!res.Succeeded)
{
foreach (IdentityError er in res.Errors)
{
ModelState.AddModelError(string.Empty, er.Description);
}
ViewBag.UserMessage = "Error Adding Role";
return View();
}
else
{
ViewBag.UserMessage = "Role Added";
return View();
}