Я настроил модель идентификации EF Core, чтобы иметь дополнительную информацию об отношениях UserRole.
Теперь я хотел бы извлечь настраиваемые поля, добавленные после входа пользователя в систему, чтобы передать их приложению.
Ниже приведены созданные классы и метод, с помощью которого я получаю информацию о пользователе.
public class ApplicationUser: IdentityUser
{
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; } = null!;
public string? UserCode { get; set; } = null!;
public string? UserExternalCode1 { get; set; } = null!;
public string? UserExternalCode2 { get; set; } = null!;
public string? UserExternalCode3 { get; set; } = null!;
public Guid? EmployeeTypeId { get; set; }
public EmployeeType? EmployeeType { get; set; } = null!;
}
public class ApplicationUserRole: IdentityUserRole<string>
{
public Guid? LineId { get; set; }
public Line? Line { get; set; } = null!;
public Guid? TerritoryId { get; set; }
public Territory? Territory { get; set; } = null!;
public Guid? BusinessUnitId { get; set; }
public BusinessUnit? BusinessUnit { get; set; } = null!;
public DateTimeOffset ValidFrom { get; set; }
public DateTimeOffset? ValidTo { get; set; }
}
ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// User Management
modelBuilder.Entity<IdentityUser>().ToTable("Users");
modelBuilder.Entity<IdentityRole>().ToTable("Roles");
modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("RolesClaims");
modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UsersClaims");
modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UsersLogins");
modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UsersRoles");
modelBuilder.Entity<IdentityUserToken<string>>().ToTable("UsersTokens");
modelBuilder.Entity<ApplicationUser>().Property(p => p.UserCode).HasMaxLength(100);
modelBuilder.Entity<ApplicationUser>().Property(p => p.UserExternalCode1).HasMaxLength(100);
modelBuilder.Entity<ApplicationUser>().Property(p => p.UserExternalCode2).HasMaxLength(100);
modelBuilder.Entity<ApplicationUser>().Property(p => p.UserExternalCode3).HasMaxLength(100);
modelBuilder.Entity<ApplicationUserRole>().Property(p => p.ValidFrom).HasDefaultValue(DateTimeOffset.Now);
}
// User Management
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
public DbSet<ApplicationUserRole> ApplicationUserRoles { get; set; }
}
Извлеките информацию о пользователе и роли:
private static async Task<AuthenticationResponseDTO> BuildToken(UsersCredentialsDTO usersCredentialsDTO, IConfiguration configuration, UserManager<IdentityUser> userManager)
{
var claims = new List<Claim>
{
new Claim("email", usersCredentialsDTO.Email)
};
var user = await userManager.FindByEmailAsync(usersCredentialsDTO.Email);
var claimsFromDB = await userManager.GetClaimsAsync(user!);
var userId = await userManager.GetUserIdAsync(user!);
var roles = await userManager.GetRolesAsync(user!);
var userName = await userManager.GetUserNameAsync(user!);
claims.AddRange(claimsFromDB);
var key = KeysHandler.GetKey(configuration).First();
var credential = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiration = DateTime.UtcNow.AddDays(1);
var securityToken = new JwtSecurityToken(issuer: null, audience: null, claims: claims, expires: expiration, signingCredentials: credential);
var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
return new AuthenticationResponseDTO
{
Token = token,
Id = new Guid(userId),
Roles = roles,
Email = userName,
Claims = claims,
Expiration = expiration
};
}
Эта строка кода
var roles = await userManager.GetRolesAsync(user!);
в настоящее время возвращает только роль Name без добавления новой информации к сущности.
Может ли кто-нибудь мне помочь?
Я новичок в Entity Framework Core, поэтому, вероятно, мне не хватает некоторых основ.
да, работает, проблем с авторизацией у меня нет, просто нужно понять, как извлечь лишнюю информацию из сущности UserRole





Если вы проверите исходный код GetRolesAsync, то именно Task<IList<string>> GetRolesAsync(TUser user) возвращает IList<string> имен ролей. Но что нужно вернуть, так это List<ApplicationUser>. Итак, нам нужно написать метод расширения для UserManager. Вы можете попробовать следующий код:
ApplicationRole.cs
public class ApplicationRole : IdentityRole
{
public string addtionalRoleInfo { get; set; }
}
UserManagerExtensions.cs
public static class UserManagerExtensions
{
public static async Task<IList<ApplicationRole>> GetAppRoles(this UserManager<IdentityUser> userManager, IdentityUser user, ApplicationDbContext dbContext)
{
var appRoles = new List<ApplicationRole>();
var userRoles = dbContext.UserRoles.Where(x => x.UserId == user.Id);
//get the role names using "GetRolesAsync"
var roles = await userManager.GetRolesAsync(user);
foreach (var role in roles)
{
//using the role names to get the full ApplicaitonRole informations from Roles table.
var appRole =dbContext.Roles.First(x=>x.Name==role);
appRoles.Add(appRole);
}
return appRoles;
}
}
Затем проверьте следующее:
public class ValuesController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly ApplicationDbContext _dbContext;
public ValuesController(UserManager<IdentityUser> userManager,RoleManager<ApplicationRole> roleManager,ApplicationDbContext dbContext)
{
this._userManager = userManager;
this._roleManager = roleManager;
this._dbContext = dbContext;
}
//To register a user "[email protected]" with role "Admin" and "IT"
[HttpGet("initial")]
public async Task initial()
{
var newuser = new IdentityUser { Email = "[email protected]" ,UserName = "Tom"};
await _userManager.CreateAsync(newuser, "Q!q11111");
await _roleManager.CreateAsync(new ApplicationRole { Id = "1", Name = "Admin", addtionalRoleInfo = "administrator" });
await _roleManager.CreateAsync(new ApplicationRole { Id = "2", Name = "IT", addtionalRoleInfo = "information technology" });
var user = await _userManager.FindByEmailAsync("[email protected]");
await _userManager.AddToRoleAsync(user,"Admin");
await _userManager.AddToRoleAsync(user, "IT");
}
//test to get roles
[HttpGet("getroles")]
public async Task<List<ApplicationRole>> GetRoles()
{
var user =await _userManager.FindByEmailAsync("[email protected]");
var approles =await _userManager.GetAppRoles(user,_dbContext);
return approles.ToList();
}
}
Результат теста
Но когда вы используете что-то вроде
[Authorize(Roles = "Admin")], это работает?