Hello I'm somehow new in ASP.NET Core, I want to check, in the controller, if a logged-in user is in a certain role, to return the appropriate view. One view with the CRUD links, the other read-only.
I have two roles :
- The Manager "CanManage" (CRUD)
- The User "CanUse"
public async Task<IActionResult> Index() {
bool isInrole = User.IsInRole("CanManage"); // First try
bool isInrole = HttpContext.User.IsInRole("CanManage"); // Second try
bool isInrole = User.HasClaim(ClaimTypes.Role, "CanManage"); // Third try
if (isInrole)
return View(await _context.Etudiants.ToListAsync());
return View("IndexReadonly", await _context.Etudiants.ToListAsync());
}
Each time the bool
is false
, any idea how to check the user roles?
CodePudding user response:
Finally, I found a solution.
After some readings, it has been said that the Roles are somehow old school, and the Claims are the actual way! (If it makes sense...)
So, I did.
Had to do few steps to replace roles with claims.
- Prepopulate the database with claims and users, inside the
ApplicationDBContext
class, in theOnModelCreating
method
protected override void OnModelCreating(ModelBuilder modelBuilder) {
// Fluent API
//...
string MANAGER_ID = Guid.NewGuid().ToString();
string BASIC_ID = Guid.NewGuid().ToString();
var passwordHasher = new PasswordHasher<IdentityUser>();
// Manager
var managerName = "[email protected]";
var manager = new IdentityUser {
Id = MANAGER_ID, // Primary key
Email = managerName,
NormalizedEmail = managerName.ToUpper(),
UserName = managerName,
NormalizedUserName = managerName.ToUpper(),
EmailConfirmed = true,
};
manager.PasswordHash = passwordHasher.HashPassword(manager, "Pass_12345");
// Basic user
var basicname = "[email protected]";
var basic = new IdentityUser {
Id = BASIC_ID, // Primary key
Email = basicname,
NormalizedEmail = basicname.ToUpper(),
UserName = basicname,
NormalizedUserName = basicname.ToUpper(),
EmailConfirmed = true,
};
basic.PasswordHash = passwordHasher.HashPassword(basic, "Pass_12345");
// Seeding the User to AspNetUsers table
builder.Entity<IdentityUser>().HasData(manager, basic);
builder.Entity<IdentityUserClaim<string>>().HasData(
new IdentityUserClaim<string> { Id = 1, UserId = MANAGER_ID, ClaimType = AppClaimType.Manage, ClaimValue = "true" },
new IdentityUserClaim<string> { Id = 2, UserId = BASIC_ID, ClaimType = AppClaimType.Basic, ClaimValue = "true" });
}
Drop-Database
in the Package Manager Console (PMC) to start freshAdd-Migration Claims
, thenUpdate-Database
- An extra class just to reference the names of the claims and policies
public class AppClaimType{
public const string Manage = "Manage Role";
public const string Basic = "Basic Role";
}
public class AppPolicyName{
public const string Management = "Management";
public const string BasicUsage = "BasicUsage";
}
- In the
Program.cs
made a policy
builder.Services.AddAuthorization(options => {
options.AddPolicy(AppPolicyName.Management,
policy => policy.RequireClaim(AppClaimType.Manage, "true"));
});
- Finally do the check in the Controller
public async Task<IActionResult> Index() {
bool hasClaim = User.HasClaim(AppClaimType.Manage, "true");
if (hasClaim)
return View(await _context.Etudiants.ToListAsync());
return View("IndexReadonly", await _context.Etudiants.ToListAsync());
}
Now the bool
gets the correct value as expected, depends on the logged-in user (basic or manager)