我正在使用实体框架实现的ASP.NET Identity 2.1.0。
身份验证工作正常但基于角色的安全性存在问
虽然我已经为用户添加了角色,但此代码返回空:
var roles= UserManager.GetRoles(User.Identity.GetUserId());
此外,基于登录用户角色的授权失败。当用户重定向到如下控制器时,应用程序会将他重定向到登录页面。
[Authorize(Roles = "Admin")]
public abstract partial class AdminAreaController : Controller
{
为了添加ASP.NET标识,首先,我创建了自定义用户类来添加配置文件数据:
public class BasemapUser : IdentityUser
{
[MaxLength(100)]
public string Name { get; set; }
[MaxLength(100)]
public string CompanyName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<BasemapUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
ClaimsIdentity userIdentity =
await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
这是DbContext类:
public class WebCoreMapDbContext : IdentityDbContext<BasemapUser>
{
public WebDbContext()
: base("WebDbContext")
{
}
public static WebCoreMapDbContext Create()
{
return new WebCoreMapDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});
}
}
我在power shell中使用EF Migration命令创建了数据库。我在IdentityUserRoles表中看到两个额外的列,我在其他ASP.NET身份示例中没有看到
我使用此代码添加默认管理员用户和角色:
public static void Start()
{
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<BasemapUserManager>();
var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
const string name = "someEmail@gmail.com";
const string password = "somePassword";
const string roleName = "Admin";
//Create Role Admin if it does not exist
IdentityRole role = roleManager.FindByName(roleName);
if (role == null)
{
role = new IdentityRole(roleName);
IdentityResult roleresult = roleManager.Create(role);
}
BasemapUser user = userManager.FindByName(name);
if (user == null)
{
user = new BasemapUser {UserName = name, Email = name};
IdentityResult result = userManager.Create(user, password);
result = userManager.SetLockoutEnabled(user.Id, false);
}
// Add user admin to Role Admin if not already added
IList<string> rolesForUser = userManager.GetRoles(user.Id);
if (!rolesForUser.Contains(role.Name))
{
IdentityResult result = userManager.AddToRole(user.Id, role.Name);
}
}
管理员用户和角色已成功存储在数据库中,但IdentityUserRoles表中存储的记录包含空值:
为什么GetRoles不会为在数据库中具有该角色的用户返回任何内容?像IsInRole这样的其他API也无法按预期工作。是因为添加到IdentityUserRoles表的外键吗?
答案 0 :(得分:4)
问题是添加到Identity表的不必要的列。
由于DbContext从IdentityDbContext扩展,我必须调用base.OnModelCreating,因为IdentityDbContext定义它来映射Identity类。我没有在导致问题的代码中调用它
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId});
}
必须改为
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId); // do not add this
// modelBuilder.Entity<IdentityUserRole>().HasKey(r => new {r.RoleId, r.UserId}); // do not add this
// other mapping codes
}