如何使用Web API 2 + AspNet Identity 2扩展IdentityRole

时间:2014-09-04 17:45:42

标签: .net entity-framework asp.net-web-api asp.net-identity asp.net-identity-2

我正在尝试在最新版本的Visual Studio 2013中扩展Web API 2(带有个人帐户)模板中提供的AspNet IdentityRole类。当我点击/ api / roles时,它返回一个空数组

身份模型

namespace API.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>, IUser, IUser<string>
{
    [NotMapped]
    public virtual UserProfile Profile { get; set; }

    public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }

    //public virtual List<ApplicationUserRole> ApplicationRoles { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager,
        string authenticationType)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        ClaimsIdentity userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        // Add custom user claims here
        return userIdentity;
    }
}

public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
    public ApplicationRole() : base() { }

}

public class ApplicationUserRole : IdentityUserRole<string>
{
    public ApplicationUserRole()
        : base()
    { }

    public virtual ApplicationRole Role { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser,ApplicationRole,string,IdentityUserLogin,ApplicationUserRole,IdentityUserClaim> 

{

     public ApplicationDbContext()
        : base("DefaultConnection")
    {
        base.Configuration.ProxyCreationEnabled = false;
    }

     public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

}

身份配置

namespace API
{
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.

public class ApplicationUserManager : UserManager<ApplicationUser, string>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,
        IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        IDataProtectionProvider dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}



public class ApplicationRoleManager : RoleManager<ApplicationRole, string>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
        : base(store)
    {
    }

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options,
        IOwinContext context)
    {
        var manager = new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
        return manager;
    }

}

}

1 个答案:

答案 0 :(得分:8)

你的错误就在这里

ApplicationDbContext : IdentityDbContext<ApplicationUser>

您的数据库上下文的范围是IdentityDbContext<ApplicationUser> 这是

的基础
IdentityDbContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>

当您希望IdentityRole作为您的角色时,ApplicationDbContext将生成ApplicationRole

将ApplicationDbContext更改为

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
{

 public ApplicationDbContext()
    : base("DefaultConnection", false)
 {
    base.Configuration.ProxyCreationEnabled = false;
 }

 public static ApplicationDbContext Create()
 {
    return new ApplicationDbContext();
 }
}

您不必覆盖OnModelCreating并在此处添加属性角色。

由于您在ApplicationUserRole中有导航属性,因此应添加configurationmapping

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<ApplicationUserRole>().HasRequired(ur => ur.Role).WithMany().HasForeignKey(ur => ur.RoleId);
}

IdentityModel.cs应该是这样的:

public class ApplicationUserRole : IdentityUserRole<string>
{
    public ApplicationUserRole()
        : base()
    { }

    public virtual ApplicationRole Role { get; set; }
}

public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
    public ApplicationRole() : base() { }

    public ApplicationRole(string name, string description)
        : base()
    {
        this.Name = name;
        this.Description = description;
    }

    public string Description { get; set; }
}

public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
{

    public ApplicationDbContext()
        : base("DefaultConnection")
    {
        base.Configuration.ProxyCreationEnabled = false;
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUserRole>().HasRequired(ur => ur.Role).WithMany().HasForeignKey(ur => ur.RoleId);
    }
}

identityconfig.cs应该是这样的:

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>, IUserStore<ApplicationUser>
{
    public ApplicationUserStore(ApplicationDbContext context)
        : base(context)
    {
    }   
}

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationDbContext>()));
        ....
    }
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, string, ApplicationUserRole>
{
    public ApplicationRoleStore(ApplicationDbContext context)
        : base(context)
    {

    }
}
public class ApplicationRoleManager : RoleManager<ApplicationRole, string>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
        : base(store)
    {
    }

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options,
        IOwinContext context)
    {
        var manager = new ApplicationRoleManager(new ApplicationRoleStore(context.Get<ApplicationDbContext>()));
        return manager;
    }
}