Home > Software engineering >  How to check if a logged in user is in a role in ASP.NET Core
How to check if a logged in user is in a role in ASP.NET Core

Time:04-06

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.

  1. Prepopulate the database with claims and users, inside the ApplicationDBContext class, in the OnModelCreating 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" });
}
  1. Drop-Database in the Package Manager Console (PMC) to start fresh
  2. Add-Migration Claims, then Update-Database
  3. 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";
}
  1. In the Program.cs made a policy
builder.Services.AddAuthorization(options => {
    options.AddPolicy(AppPolicyName.Management,
        policy => policy.RequireClaim(AppClaimType.Manage, "true"));
});
  1. 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)

  • Related