How to create roles in ASP.NET Core and assign them to users? How to create roles in ASP.NET Core and assign them to users? asp.net asp.net

How to create roles in ASP.NET Core and assign them to users?


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


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.


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.