简体   繁体   中英

How can I seed users and roles in my asp.net core 3.1 application?

I tried using protected override void OnModelCreating(ModelBuilder builder) in my IdentityDataContext class and creating a migration that will seed this data:

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
        const string ADMIN_ID = "b4280b6a-0613-4cbd-a9e6-f1701e926e73";
        const string ROLE_ID = ADMIN_ID;
        builder.Entity<IdentityRole>().HasData(new IdentityRole
        {
            Id = ROLE_ID,
            Name = "admin",
            NormalizedName = "ADMIN"
        });
        builder.Entity<MyIdentityUser>().HasData(new MyIdentityUser
        {
            Id = ADMIN_ID,
            UserName = "myemail@myemail.com",
            NormalizedUserName = "MYEMAIL@MYEMAIL.COM",
            Email = "myemail@myemail.com",
            NormalizedEmail = "MYEMAIL@MYEMAIL.COM",
            EmailConfirmed = true,
            PasswordHash = "AQABBAEABCcQAABAEBhd37krE/TyMklt3SIf2Q3ITj/dunHYr7O5Z9UB0R1+dpDbcrHWuTBr8Uh5WR+JrQ==",
            SecurityStamp = "VVPCRDAS3MJWQD5CSW2GWPRADBXEZINA",
            ConcurrencyStamp = "c8554266-b401-4519-9aeb-a9283053fc58"
        });
        builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
        {
            RoleId = ROLE_ID,
            UserId = ADMIN_ID
        });
    }

which seems to work, but I cannot access my endpoint in Razor Page decorated with Authorize atribute. It's strange because I have all this data in my database. I can log in as this user and I see that there is "admin" role in AspNetRoles table. I have also user mapped to role correctly in AspNetUserRoles table.

[Authorize(Roles="admin")]
public class IndexModel : PageModel
{
    public async Task<IActionResult> OnGetAsync()
    {
        return Page();
    }

}

I'm being redirected to access denied page when logged as the user above which according to database has the admin role.

I saw that some people try to do this seed method in Configure method in Startup class, but I'm currently having trouble with dependency injection when i try to do this with RoleManager and UserManager:

System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.

I was almost there. It was not obvious at first, but I needed to add .AddRoles<IdentityRole>() line in my Configure method of IdentityHostingStartup.cs file.

It's mentioned at the end of Role-based authorization page from asp.net core 3.1 documentation: link to the documentation

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}

I thought that roles are already taken into consideration and I don't need to explicitly add this functinality.

It should be stated on top of the page that in order to add role-based authorization you need to add .AddRoles<IdentityRole>() to your Configure method. Instead you are presented with many combinations of Authorization attribute and then at the bottom there is a brief paragraph "Add Role services to Identity" which gives no explanation that this is what makes it all to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM