Reputation: 1767
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 = "[email protected]",
NormalizedUserName = "[email protected]",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
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.
Upvotes: 8
Views: 7848
Reputation: 1767
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.
Upvotes: 8