Authorize和GetRoles在ASP.NET身份中不起作用

时间:2014-10-20 08:47:46

标签: c# asp.net-mvc entity-framework asp.net-identity-2

我正在使用实体框架实现的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身份示例中没有看到

Extra columns in IdentityUserRoles

我使用此代码添加默认管理员用户和角色:

        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表中存储的记录包含空值:

Null value

为什么GetRoles不会为在数据库中具有该角色的用户返回任何内容?像IsInRole这样的其他API也无法按预期工作。是因为添加到IdentityUserRoles表的外键吗?

1 个答案:

答案 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
    }