【问题标题】:Understanding Asp.Net Identity key points了解 Asp.Net Identity 关键点
【发布时间】:2015-08-18 07:30:43
【问题描述】:

我是一名 Asp.net 开发人员,但对 Asp.net Identity 框架非常陌生。我一直在研究示例应用程序并遵循了一些关于身份的教程,但我仍然无法完全掌握这个概念。我对 Asp.net 会员身份有非常坚定的控制,但 Identity 似乎与会员身份完全不同。我将解释我到目前为止所做的事情。

我正在创建一个简单的应用程序,我在其中遵循代码优先方法。我为 User 创建了实体模型,它继承自 IdentityUser 并有一些额外的字段。下面是用户的实体模型。

public class User : IdentityUser
{
    public int? CompanyID { get; set; }

    public bool? CanWork { get; set; }

    public bool? CanSearch { get; set; }

    public Company Company { get; set; }
}

现在在示例中,人们使用名称 ApplicationUser,但出于我自己的目的,我使用了名称 User。在 User 或 ApplicationUser 模型中还有一个方法是,

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
    {
        CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

我无法理解这种方法的目的。同样从一个示例中,我将以下模型用于角色,

public class Role : IdentityRole
{
    public Role()
    {

    }

    public Role(string roleName, string description)
        : base(roleName)
    {
        this.Description = description;
    }

    public string Description { get; set; }
}

我知道添加了一个额外的字段,但我无法理解重载构造函数的目的。

上述混淆是次要的。我的主要困惑是我很熟悉,当我创建实体模型时,我使用 DbSet 和 DbContext,当我调用任何实体框架方法来访问数据库时,无论我遵循哪种方案,都会创建/删除数据库。

在 Identity 中,哪个方法负责在数据库中创建 Identity 表?我有一个 IdentityConfig 文件,我在其中声明了 ApplicationUserManager 和 ApplicationSignInManager。我还有一个启动文件。以前我在 App_Start 文件夹中只有一个启动文件,当我运行应用程序并尝试访问任何 Identity 方法时,它给了我错误并且没有创建数据库。然后我将该类设置为部分类,并在根目录中创建了另一个具有相同名称的部分类,然后异常消失并创建了表。那么Startup类负责创建Identity表呢? AspNetUsers 中自动创建了额外的列,例如 PhoneNumber、PhoneNumberConfirmed、TwoFactorEnabled。我不需要这些额外的列。我可以删除这些吗?我可以更改创建的身份表的名称吗?

我知道这些是非常基本的问题,根本不是一个问题,但如果我无法为初学者找到一些基本教程或示例,那将是非常有益的。我所发现的是描述那些我不需要或让我感到困惑的东西。我想了解并控制 Identity 在我的应用程序中应该如何工作,但到目前为止,在我看来,我既没有完全掌握它,也无法根据我的需要进行调整。它就像教程和示例正在教我如何造句,但我无法理解字母。 :(

【问题讨论】:

    标签: asp.net-mvc-5 entity-framework-6 asp.net-identity-2


    【解决方案1】:

    首先,您必须定义模型 - 正如您正在做的那样 - 实现正确的接口。
    假设您想为您的应用程序创建一个用户:

    public class MyUser : IdentityUser<string, MyUserLogin, MyUserRole, MyUserClaim>
    {
        public string CompanyName { get; set; }
    }
    

    如您所见,我已经实现了IdentityUser 接口(命名空间Microsoft.AspNet.Identity.EntityFramework)。

    我已经指定了我想为我的主键(字符串)使用什么类型的标识符,并包含了我的自定义对象来管理登录、角色和声明。

    现在我们可以定义角色对象了:

    public class MyRole : IdentityRole<string, MyUserRole>
    {
    }
    

    我再次定义了一个类型和类,用于管理属于某个角色的用户。

    public class MyUserRole : IdentityUserRole<string>
    {
    }
    

    MyUserLogin 将实现IdentityUserLogin&lt;string&gt;
    MyUserClaim 将实现IdentityUserClaim&lt;string&gt;

    如您所见,每个接口都需要一个主键类型。

    第二步,创建用户存储:

    public class MyUserStore:  UserStore<MyUser, MyRole, string, MyUserLogin, MyUserRole, MyUserClaim>
    {
        public MyUserStore(MyContext context)
            : base(context)
        {
        }
    }
    

    我们再次定义了我们想要使用的用户、角色、登录名等。
    我们需要UserStore,因为我们的 UserManager 需要一个。

    如果您计划管理角色并将角色与每个用户关联,您必须创建您的 RoleStore 定义。

    public class MyRoleStore : RoleStore<MyRole, string, MyUserRole>
    {
        public DaufRoleStore(ApplicationDatabaseContext context) : base(context)
        {
        }
    }
    

    现在您可以创建您的UserManager。 UserManager 是真正的responsible 将更改保存到UserStore

    public class ApplicationUserManager : UserManager<MyUser, string>
    {
        public ApplicationUserManager(IUserStore<MyUser, string> store)
            : base(store)
        {
    
        }
    
        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
            var manager = new ApplicationUserManager(new MyUserStore(context.Get<MyContext>()));
    
            manager.UserValidator = new UserValidator<MyUser, string>(manager)
            {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
            };
    
            manager.PasswordValidator = new PasswordValidator()
            {
            RequiredLength = 5,
            RequireNonLetterOrDigit = false,     // true
            // RequireDigit = true,
            RequireLowercase = false,
            RequireUppercase = false,
            };
    
            return (manager);
        }
    }
    

    这个类有一个静态方法,它会为你创建一个新的 UserManager。
    有趣的是,您可以包含一些您可能需要验证密码等的验证规则。

    最后一件事是创建或数据库上下文。

    public class MyContext : IdentityDbContext<MyUser, MyRole, string, MyUserLogin, MyUserRole, MyUserClaim>
    {
        public MyContext(): base("<your connection string here>")
        {
    
        }
    
        public static MyContext Create()
        {
            return new MyContext();
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<MyUser>()
                .ToTable("Users");
    
            modelBuilder.Entity<MyRole>()
                .ToTable("Roles");
    
            modelBuilder.Entity<MyUserRole>()
                .ToTable("UserRoles");
    
            modelBuilder.Entity<MyUserClaim>()
                .ToTable("UserClaims");
    
            modelBuilder.Entity<MyUserLogin>()
                .ToTable("UserLogins");
        }
    }
    

    如您所见,我使用模型构建器更改了所有表的名称。 您可以在此处定义键或字段类型或表关系。

    这是您要在上下文中附加要管理的自定义类的地方:

    public DbSet<MyCustomer> Customers{ get; set; }
    

    同样MyContext 有一个Create 方法,它返回一个新的上下文:

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

    现在你应该有一个启动类,你将在其中引导你的东西:

    [assembly: OwinStartup(typeof(ASPNETIdentity2.Startup))]
    
    namespace ASPNETIdentity2
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.CreatePerOwinContext(MyContext.Create);
                app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            }
        }
    }
    

    在这里,您将创建可以在应用程序中使用的数据库上下文和用户管理器。

    注意第一行:

    [assembly: OwinStartup(typeof(ASPNETIdentity2.Startup))]
    

    这是必需的,因为您要告诉您的环境是需要在...启动时调用的启动类。

    现在在您的控制器中,您可以简单地参考您的 UserManager 执行以下操作:

    HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    

    如何创建表?

    在 Visual Studio 中,转到工具 -> NuGet Packager Manager -> 包管理器控制台。

    在窗口中有一个“默认项目”组合框。选择您的 ASP.NET MVC 项目。
    运行这个命令:

    Enable-Migrations
    

    它将在名为 Migrations 的新文件夹中创建一个文件 Configuration.cs
    如果您想创建您的数据库,您需要打开该文件并将 AutomaticMigrationsEnabled 更改为 true:

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }
    

    同样,从Package Manager Console,您可以运行:

    Update-Database
    

    您的所有表格都将出现在您的数据库中。不要忘记您的连接字符串。

    您可以下载此github project 以了解一切如何运作。
    您可以查看这些two answers 和其他一些信息。

    两者中的first 有一些指向博客的链接,您可以在其中了解所有这些内容。

    注意:

    如果您想自定义环境的每一部分,您必须完成所有这些操作。

    【讨论】:

    • 哇。谢谢。您提出的细节非常容易理解,我非常感谢您的努力。它简洁而完整地描述了所有事物。祝你有美好的一天。
    • 很高兴我在某种程度上提供了帮助。祝你好运。我不是特别喜欢那些乱七八糟的东西,但这就是它的工作方式。干杯。
    猜你喜欢
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2022-11-16
    • 2015-08-09
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    相关资源
    最近更新 更多