ASP.NET Identity Get All Roles of Logged in User

asp.net identity get all roles of logged in user

Controller.User.Identity is a ClaimsIdentity. You can get a list of roles by inspecting the claims...

var roles = ((ClaimsIdentity)User.Identity).Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value);

--- update ---

Breaking it down a bit more...

using System.Security.Claims;

// ........

var userIdentity = (ClaimsIdentity)User.Identity;
var claims = userIdentity.Claims;
var roleClaimType = userIdentity.RoleClaimType;
var roles = claims.Where(c => c.Type == ClaimTypes.Role).ToList();

// or...
var roles = claims.Where(c => c.Type == roleClaimType).ToList();

.NET Core 2.1 Identity get all users with their associated roles

I have now implemented the following solution.

As CodeNotFound pointed out in the comments, IdentityUser used to have a Roles property. This is no longer the case in .NET Core. This comment/issue on GitHub seems to be the current solution for .Net Core. I have attempted to implemented it with the following code:

ApplicationUser

public class ApplicationUser : IdentityUser
{
public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

ApplicationUserRole

public class ApplicationUserRole : IdentityUserRole<string>
{
public virtual ApplicationUser User { get; set; }
public virtual ApplicationRole Role { get; set; }
}

ApplicationRole

public class ApplicationRole : IdentityRole
{
public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

DBContext

public class ApplicationDbContext
: IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
ApplicationUserRole, IdentityUserLogin<string>,
IdentityRoleClaim<string>, IdentityUserToken<string>>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);

builder.Entity<ApplicationUserRole>(userRole =>
{
userRole.HasKey(ur => new { ur.UserId, ur.RoleId });

userRole.HasOne(ur => ur.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();

userRole.HasOne(ur => ur.User)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
}
}

Startup

services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();

Finally, make sure when you're using it that you eagerly load the User's UserRoles, and then the UserRole's Role like so:

this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();

I had an issue where the Role property of each UserRole was null and this was resolved by adding in the .ThenInclude(ur => ur.Role) part.

Microsoft doc on multi-level eager loading: https://learn.microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels

ASP Core 2.2 update

Inherent from IdentityUserRole<Guid> not string
You may also need to remove the code in the ModelBuilder to get migrations working.

Get role/s of current logged in user in ASP.NET Core MVC

You may want to consider trying to load the actual ApplicationUser object via the FindByEmail() or some other method and passing that object into the GetRolesAsync() method as seen below :

// Resolve the user via their email
var user = await _userManager.FindByEmailAsync(model.Email);
// Get the roles for the user
var roles = await _userManager.GetRolesAsync(user);

A more complete example might look like :

[HttpPost("Auth/SignIn")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SignIn(SignInViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, true, false);
if (result.Succeeded)
{
// Resolve the user via their email
var user = await _userManager.FindByEmailAsync(model.Email);
// Get the roles for the user
var roles = await _userManager.GetRolesAsync(user);

// Do something with the roles here
}
else
{
// Uh oh....
}
}

// Something is probably wrong, provide the form again....
return View(model);
}

Asp.net identity - How to maintain logged in user role?

I see at least three solutions for your problem:

  1. Use a claim transformation to filter the role claims, to match a role the user choose. You can use a claim transformation middleware or you can filter the claims during login (be aware, that you do not know the user roles BEFORE login, and afterwards filtering might be too late). PRO Does not necessarily need session state; CON User can not choose during runtime.

  2. Store the role in the session and authenticate against that role. Make sure, that you check against the role claims, when the user chooses his role. PRO User might change role without re-sign-in. CON Needs session state (Might be an issue in farm environments).

  3. Don't do it at all and I'm totally serious about that. Provide your user a clean interface, that makes him know, what role he has and use areas and other technics to separate the concerns.

get current user's role

You can get a list of Roles from the GetRoles method. (From the link)

  string[] rolesArray;

public void Page_Load()
{
RolePrincipal r = (RolePrincipal)User;
rolesArray = r.GetRoles();
...//extra code
}

How to get role name for user in Asp.Net Identity

In your code, user object represents the AspNetUsers table which has a navigation property Roles which represents the AspNetUserInRoles table and not the AspNetRoles table.
So when you try to navigate through

user.Roles.FirstOrDefault()

it gives you the AspNetUserInRoles which stores UserId and RoleId.

Instead you could try UserManger's GetRoles method which will return you List<string> of roles user is assigned. But as you mentioned it will be only one role hence you can take first value from the result of GetRoles method.

Your function should be similar to one given below:

public async string GetUserRole(string EmailID, string Password)
{
var user = await _userManager.FindAsync(EmailID, Password);
string rolename = await _userManager.GetRoles(user.Id).FirstOrDefault();
return rolename;
}

Get all roles in asp.net core identity using a separate class

Create a class:

public class RoleUtility 
{
private readonly RoleManager<IdentityRole> _roleManager;

public RoleUtility(RoleManager<IdentityRole> roleManager)
{
_roleManager = roleManager;
}

public void PopulateRolesList(RegisterViewModel model)
{
model.Roles = _roleManager.Roles?.ToList();
}
}

Extract the interface:

public interface IRoleUtility
{
void PopulateRolesList(RegisterViewModel model);
}

The RoleUtility class declaration become:

public class RoleUtility: IRoleUtility

Then, in your Startup class :

public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IRoleUtility, RoleUtility>();
}

Your controller code become:

public AdminController(
UserManager<ApplicationUser> userManager,
ILogger<AccountController> logger,
IEmailSender emailSender,
IRoleUtility roleUtility,
SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_logger = logger;
_emailSender = emailSender;
_roleUtility = roleUtility;
_signInManager = signInManager;
}

private void PuplateRolesList(RegisterViewModel model)
{
_roleUtility.PopulateRolesList(model);
}

Getting All Users and All Roles through asp.net Identity

In ASP.NET Identity 1.0, you'll have to get this from the DbContext itself...

var context = new ApplicationDbContext();
var allUsers = context.Users.ToList();
var allRoles = context.Roles.ToList();

In ASP.NET Identity 2.0 (currently in Alpha), this functionality is exposed on the UserManager and RoleManager...

userManager.Users.ToList();
roleManager.Roles.ToList();

In both versions, you would be interacting with the RoleManager and UserManager to create roles and assign roles to users.



Related Topics



Leave a reply



Submit