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:
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.
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).
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
Characters in String Changed After Downloading HTML from the Internet
How to Return a Reference to a Variable in C#
Can You Have a Property Name Containing a Dash
How to Get the Lowercase Name of an Object, Even When Null, in C#
Mvc/Jquery Validation Does Not Accept Comma as Decimal Separator
How to Get JSON Response from a 3.5 Asmx Web Service
Wpf Databinding to Interface and Not Actual Object - Casting Possible
Display Unicode Characters in Converting HTML to PDF
Conditional Compilation Depending on the Framework Version in C#
.Net - Windowstyle = Hidden VS. Createnowindow = True
.Net Framework 3.5 and Tls 1.2
Cannot Convert Lambda Expression to Type 'System.Delegate'