I'm new to ASP.NET Identity, and am struggling with roles. My previous experience in in desktop apps (where we obviously couldn't use ASP.NET Identity, and mainly rolled our own roles), and we usually added an enum
for the roles. This enabled us to refer to them unambiguously in code.
ASP.NET Identity seems to require roles stored in the database. My main issue with this is that we can't guarantee that everyone (all developers, the test and production databases) will have the same data in our databases. By using an enum
, the data is hard-coded in the code, so no possibility of ambiguity.
A secondary (but still very important) issue is that roles seem to rely on you using hard-coded strings:
[Authorize(Roles = "SomeRole")]
public IActionResult SomeAction() => View();
This seems brittle. It's all too easy to mistype the role name, and what if we want to change the name? We'd have to hunt down every instance of the hard-coded string and change it.
To clarify, roles are being used to restrict access to certain areas of the web site. We will have a fixed set of roles, which will rarely change. If they do change, the code will need to change with them, so dynamic access to roles (eg via a CRUD section of the site) is pointless.
Can we do this? If not, how do we get around the issue of knowing how to refer to roles that may not exist?
To avoid mistyping, you could try const
instead of enum
.
RoleConst
public class RoleConst
{
public const string Admin = "Admin";
public const string User = "User";
}
Insert Role
public class Program
{
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
RoleManager<IdentityRole> roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
if (roleManager.Roles.Count() == 0)
{
//insert role
roleManager.CreateAsync(new IdentityRole(RoleConst.Admin)).ConfigureAwait(true);
roleManager.CreateAsync(new IdentityRole(RoleConst.User)).ConfigureAwait(true);
}
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
Use Authorize
with RoleConst
[Authorize(Roles = RoleConst.Admin)]
public IActionResult Privacy()
{
return View();
}