正确使用Microsoft.AspNet.Identity 2.0

Pat*_*ick 12 c# asp.net-mvc dbcontext asp.net-identity

我迷失了使用MVC 5模板附带的身份验证方法.

我需要将CreateBy用户包含在一个名为client的实体中,所以经过一些研究我得出了这个:

模型:

[Table("Clients")]
public partial class Client
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public virtual int UserCreated_Id { get; set; }

    [ForeignKey("UserCreated_Id")]
    public virtual ApplicationUser UserCreated { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器方法:

client.UserCreated_Id = User.Identity.GetUserId<int>();
Run Code Online (Sandbox Code Playgroud)

但我必须改变身份模型中的几乎所有内容:

public class ApplicationUser : IdentityUser
Run Code Online (Sandbox Code Playgroud)

public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
Run Code Online (Sandbox Code Playgroud)

因此,差不多有30个变化.

但现在我有2个DbContext:

身份背景:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationDbContext() : base("IPDB") {}

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的应用背景:

public class MyDbContext : DbContext
{
    public MyDbContext() : base("IPDB")
    {

        // Tells Entity Framework that we will handle the creation of the database manually for all the projects in the solution
        Database.SetInitializer<MyDbContext>(null);
    }

    public DbSet<Client> Clients { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ANOTHER CHANGE I HAD TO MADE TO BE ABLE TO SCAFFOLDING
        modelBuilder.Entity<ApplicationUserLogin>().HasKey<int>(l => l.UserId);
        modelBuilder.Entity<ApplicationRole>().HasKey<int>(r => r.Id);
        modelBuilder.Entity<ApplicationUserRole>().HasKey(r => new { r.RoleId, r.UserId });
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:

  • 我需要2个DbContext吗?
  • 我是否正确地将用户与客户端实体相关联?
  • 我需要创建一个包含所有用户和附加信息的列表,我是否会从2个DbContext中读取信息?

拜托,我需要一些明确的指导,因为我现在非常困惑,我真的很想建立优秀的代码,我认为情况并非如此.

And*_*bel 4

ApplicationUser 上的 Id 类型

ASP.NET Identity 2.0 非常灵活,同时还提供了一些在大多数情况下都可以使用的默认实现。MVC 5 模板在大多数地方使用默认实现,但在某些情况下会添加一些额外的内容以使自定义更容易。

在内部 ASP.NET Identity 始终使用IdentityUser<...>. 所有这些模板参数都提供了一种选择您自己的密钥类型的方法,这意味着您还必须选择您自己的 IdentityUserRole 类型(因为它包含密钥)。

还有使用字符串作为键的便捷默认实现。该字符串的值是 GUID 的字符串表示形式。

public class IdentityUser : 
  IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
{
  /// <summary>
  /// Constructor which creates a new Guid for the Id
  /// </summary>
  public IdentityUser()
  {
    this.Id = Guid.NewGuid().ToString();
  }
Run Code Online (Sandbox Code Playgroud)

在数据库中使用字符串作为主键并不常见,但对于安全敏感的东西来说这是有意义的。数据库之间复制的数据不存在 ID 冲突、给用户带来错误权限的风险。

在您的情况下,您需要选择:使用带有字符串 PK 的默认实现或将 id 更改为 int。在后一种情况下,正如您所发现的,您必须更改身份模型中的“几乎所有内容”。尽管我认为您可以不实现自己的ApplicationRole. 应该可以直接声明ApplicationUser

public class ApplicationUser: IdentityUser<int, IdentityUserLogin<int>, IdentityUserRole<int>....>
Run Code Online (Sandbox Code Playgroud)

数据库上下文

在大多数情况下,单个DbContext应用程序就足够了。如果使用多个 DbContext,它们应该用于彼此不相关的不同的不同数据集。当您设置了Client与它们相关的类时ApplicationUser,它们应该位于同一个DbContext. 该模板试图通过命名来传达DbContext应用程序上下文的main 应该继承的思想。使用那个,并用你自己的东西扩展它。我通常会重命名它并将其移动到其他地方,但我仍然只有一个并让它继承。IdentityDbContext<>ApplicationDbContextDbContextIdentityDbContext<>

推出您自己的身份解决方案

除非您真的非常清楚自己在做什么,否则不要推出自己的身份解决方案。使用已通过外部审查强化安全性的现有方案。如果您对 ASP.NET Identity 不满意,您可以查看Brock Allen 的 Identity restart

为了可信度(是的,我今天是一名赏金猎人):官方 ASP.NET 文档链接到我的博客