Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom roles to ASP.NET Core

I've found this answer but it doesn't seem to fit in my ASP Net Core project.

Things I am trying to understand:

  • How can I add a custom role. I've even looked directly in my MySQL database (table aspnetroles), but I don't know what to use as Id and ConcurrencyStamp.
  • Where do I put the code to seed the database with these new roles: in Startup? in Register under AccountController?
  • How do I tie this new role to a user? I've even looked through the tables and I don't know how to assign the data (there is no user2role or aspnetusers.role_id).
like image 347
Xavier Peña Avatar asked Feb 12 '17 14:02

Xavier Peña


3 Answers

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)
    {
        //adding customs roles : Question 1
        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 2
                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"],
        };

        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 : Question 3
                await UserManager.AddToRoleAsync(poweruser, "Admin");

            }
       }
    }

and then you could call the await CreateRoles(serviceProvider); method from the Configure method in the Startup class. ensure you have IServiceProvider as a parameter in the Configure class.

Edit: If you're using ASP.NET core 2.x, my article here provides a much detailed experience. here

like image 177
Temi Lajumoke Avatar answered Oct 24 '22 08:10

Temi Lajumoke


In addition to Temi's detailed answer, remember to replace

 services.AddDefaultIdentity<IdentityUser>()
            .AddEntityFrameworkStores<DbContext>();

With

 services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<DbContext>();

Also, make sure that the types specified in AddIdentity<> is the same as the types called in serviceProvider.GetRequiredService<>

For the above, our types called in serviceProvider.GetRequiredService<> in Configure.cs would be

 var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
 var userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();

Another important thing to note is that since CreateRoles(IServiceProvider) (from Temi's answer) is an async method, to call it in Configure method (which return void), you can use CreateRoles(serviceProviderInstance).Wait(); Hope this helps.

like image 21
elfico Avatar answered Oct 24 '22 07:10

elfico


Adding to Temi's answer and Xavier's comment to it, my experience with this was a little different using asp.net-core-2.

In order to get this working I had to add the IServiceProvider as a parameter of the Configure method to get an instance of it.

public void Configure(
    IApplicationBuilder App,
    IHostingEnvironment Env,
    ILoggerFactory LoggerFactory,
    IServiceProvider ServiceProvider
)
{
    /* trimmed */

    CreateRoles(ServiceProvider).Wait();
}
like image 3
derpasaurus Avatar answered Oct 24 '22 06:10

derpasaurus