7

I've looked for this in Stackoverflow and so far it appears there are plenty of questions on adding roles in Identity 1 & 2 but its different in Identity 3.

I want to seed roles in the database. I have just two. I intended to use _roleManager which I have injected into the class. Thats fine. My problem is.. there doesnt appear to be any method to actually add a role.. Using CreateAsync is for adding the user to the role.. how do you code to add a role using "_userManager" or do you have to do it another way?

Community
  • 1
  • 1
si2030
  • 3,895
  • 8
  • 38
  • 87
  • `_roleManager` is for creating roles and `_userManager` is for adding users to the roles. I've posted an answer to help – jamiedanq Apr 23 '16 at 07:18
  • I have [a project here](https://github.com/joeaudette/cloudscribe) that may interest you, it implements multi-tenant user and role management with identity 3 – Joe Audette Apr 23 '16 at 11:36

2 Answers2

7

EDIT

Identity

In Identity RoleManager is for creating roles and UserManager is for adding users to roles. This is an example to point you in the right direction. The code below is for creating a new role Administrator

if (!roleManager.RoleExists("Administrator"))
            {
                MyIdentityRole newRole = new MyIdentityRole("Administrator", "Administrators can do something with data");
                roleManager.Create(newRole);
            }  

EDIT

Further, this is for adding a user to a role and this also an example:

 \\assuming you test if the user has been assigned to the role "Administrator" before adding them to that role

 if(RoleAdministrator == true){
           userManager.AddToRole(User.Id, "Administrator");
       }
jamiedanq
  • 967
  • 7
  • 12
  • I have been playing with this for the last hour or so and it appears in Identity 3, rolemanager does not have create... or any method that will create a role.. I counted 22 methods for roleManager... – si2030 Apr 23 '16 at 09:57
  • 1
    Curious: why using a different approach with Identity 3? RoleManager still exists and is clearly the recommended approach to manage roles. – Kévin Chalet Apr 23 '16 at 11:49
  • @si2030 roleManager should have the `create` Method. You can find it here https://msdn.microsoft.com/en-us/library/dn613286(v=vs.108).aspx – jamiedanq Apr 23 '16 at 18:40
  • 1
    In Identity Core it'll be `createAsync`. https://docs.asp.net/projects/api/en/latest/autoapi/Microsoft/AspNetCore/Identity/RoleManager-TRole/index.html#methods – bvpb Aug 15 '16 at 22:47
  • 1
    You don't need to check if role exists. It's part of the default model in `RoleValidator`. `var newRole = new ApplicationRole { Name = model.RoleName, Description = model.RoleDescription }; var result = await roleManager.CreateAsync(newRole); if (result.Succeeded) // do something else // do something else - error will be in result.errors { foreach (var error in result.Errors) // do something with error }` – CFreitas Aug 26 '16 at 13:48
1
public class SeedData
{
    private const string _adminRoleName = "admin";
    private string _adminEmail = "admin@demo.com";
    private string _adminPassword = "P@ssw0rd!PK";

    private string[] _roles = new string[] { _adminRoleName, "supervisor" };

    private readonly RoleManager<IdentityRole<Guid>> _roleManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public  static async Task Run(IServiceProvider serviceProvider)
    {
        using (var serviceScope =serviceProvider
                                 .GetRequiredService<IServiceScopeFactory>()
                                 .CreateScope())
        {
            var instance = serviceScope.ServiceProvider.GetService<SeedData>();
            await instance.Initialize();

            var context = serviceScope.ServiceProvider.GetService<AppDbContext>();
            if (!context.Products.Any())
            {
               // Seed Other entities Here
            }

            await context.SaveChangesAsync();
        }
    }

    public SeedData(UserManager<ApplicationUser> userManager, 
                                  RoleManager<IdentityRole<Guid>> roleManager)
    {
        _roleManager = roleManager;
        _userManager = userManager;
    }

    public async Task Initialize()
    {
        foreach (var role in _roles)
        {
            if (!await _roleManager.RoleExistsAsync(role))
            {
                await _roleManager.CreateAsync(new IdentityRole<Guid>(role));
            }
        }

        var adminUsers = await _userManager.GetUsersInRoleAsync(_adminRoleName);
        if (!adminUsers.Any())
        {
            var adminUser = new ApplicationUser()
            {
                Id = Guid.NewGuid(),
                Email = _adminEmail,
                UserName = _adminEmail
            };

            var result = await _userManager.CreateAsync(adminUser, _adminPassword);
            if(result.Success)
            {
               await _userManager.AddToRoleAsync(adminUser, _adminRoleName);
            }
       }         
   }
}

In your Program.cs

public static void Main(string[] args)
{
     var host = BuildWebHost(args);

     using (var scope = host.Services.CreateScope())
     {
         var services = scope.ServiceProvider;
         try
         {
              SeedData.Run(services).Wait();
         }
         catch (Exception ex)
         {
             var logger = services.GetRequiredService<ILogger<Program>>();
             logger.LogError(ex, "Error while seeding database.");
         }
     }

      host.Run();
  }

Might be helpful to someone :)

dnxit
  • 7,118
  • 2
  • 30
  • 34