【问题标题】:SimpleMembership with custom database schema in ASP.NET MVC 4SimpleMembership 与 ASP.NET MVC 4 中的自定义数据库架构
【发布时间】:2012-09-03 19:37:30
【问题描述】:

我想启用 ASP.NET MVC 4 的 SimpleMembership API 以与我自己的数据库架构集成。我的数据库中有一个名为Users 的简单表格,其中包含以下字段:

  • 身份证
  • 姓名
  • 密码
  • 电子邮件
  • 已删除

我已经配置了 SimpleMembership API 以使用我的数据库:

WebSecurity.InitializeDatabaseConnection("MyStuff", "Users", "Id", "Name", autoCreateTables: true);

我也可以插入用户:

WebSecurity.CreateUserAndAccount(model.UserName, model.Password, 
                                 new 
                                 { 
                                        IsDeleted = false, 
                                        Email = "sampledata@gmail.com"                
                                 });

但是,Password 字段(或者它的哈希)没有插入到 Users 表中(当然),它插入到另一个名为 webpages_Membership 的表中,该表是使用 InitializeDatabaseConnection 调用创建的,包含许多不必要的信息我不需要。

另外,我还有其他自动创建的表,称为 pages_OAuthMembership、webpages_Roles 和 pages_UsersInRoles,我不需要这些表。

我已经尝试将表生成设置为 false:

WebSecurity.InitializeDatabaseConnection("MyStuff", "Users", "Id", "Name", autoCreateTables: false);

但在这种情况下,CreateUserAndAccount 调用会抛出异常,因为它找不到 pages_Membership 表。

当我想使用 SimpleMembership API 时,看起来需要这些表。

我的问题是:如果我只想要一个简单的 Users 表而仅此而已,在这种情况下我应该怎么做?

我是否必须自己编写整个成员资格处理和身份验证逻辑(哈希码生成等)?

【问题讨论】:

    标签: asp.net .net asp.net-membership asp.net-mvc-4 simplemembership


    【解决方案1】:

    我向产品团队提出了同样的问题。

    SIMPLE 成员的设计目标是尽可能简单地开箱即用。

    因此,就表格而言,确实不可能进行自定义。 推荐的解决方法是,仍然使用 ASP.NET 成员资格 (SqlMembershipProvider)。

    【讨论】:

    • 好的,谢谢!也许我会编写我的自定义身份验证逻辑。
    • 不!请不要这样做! :-)
    • 没有什么可以阻止您使用 EF 获取其他用户数据。 weblogs.asp.net/jgalloway/archive/2012/08/29/…
    • 我来这里是为了发布与 James 相同的链接,这或多或少与 Simple Membership 的意图是开箱即用的简单性的想法相矛盾 - 最初的会员资格提供者在这方面做得很好.至少据称,新的提供程序被设计为更易于扩展
    • 这个答案具有误导性。可以包含和扩展现有系统。如果开箱即用的体验未提供您同意的架构,您可以轻松实现自己的 SimpleMembershipProvider 来创建和利用您自己设计的架构。
    【解决方案2】:

    可以定制。

    您可以从the aspnetwebstack project on CodePlex 获取SimpleMembershipProvider 的源代码,因为这是在数据库架构和运行时环境之间发生映射的地方,您可以修改此代码以修改/替换架构、语句等以匹配您的需要(不用太头疼,IMO。)

    【讨论】:

      【解决方案3】:

      1 - 您需要启用迁移,最好使用 EntityFramework 5。在 NuGet 包管理器中使用 Enable-Migrations

      2 - 移动你的

      WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 
      

      到 YourMvcApp/Migrations/Configuration.cs 类中的 Seed 方法

          protected override void Seed(UsersContext context)
          {
              WebSecurity.InitializeDatabaseConnection(
                  "DefaultConnection",
                  "UserProfile",
                  "UserId",
                  "UserName", autoCreateTables: true);
      
              if (!Roles.RoleExists("Administrator"))
                  Roles.CreateRole("Administrator");
      
              if (!WebSecurity.UserExists("lelong37"))
                  WebSecurity.CreateUserAndAccount(
                      "lelong37",
                      "password",
                      new {Mobile = "+19725000000", IsSmsVerified = false});
      
              if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
                  Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
          }
      

      现在 EF5 将负责创建您的 UserProfile 表,之后您将调用 WebSecurity.InitializeDatabaseConnection 以仅向已创建的 UserProfile 表注册 SimpleMembershipProvider,同时告诉 SimpleMembershipProvider 哪一列是 UserId 和 UserName。我还展示了一个示例,说明如何在 Seed 方法中添加用户、角色并将两者与自定义 UserProfile 属性/字段相关联,例如用户的手机(号码)。

      3 - 现在,当您从包管理器控制台运行 update-database 时,EF5 将为您的表提供所有自定义属性

      更多参考请参考这篇文章的源代码: http://blog.longle.io/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

      【讨论】:

      • 我认为这篇博文是关于另一个主题的:使用 EF 代码迁移播种数据。我知道我可以将任何属性添加到我的 User 表(例如 Mobile 字符串),我的问题不是关于这个,而是关于重写/自定义自动生成的 SimpleMembership 表的整个架构。
      【解决方案4】:

      您可以将 OAUth 与 ASP.NET 通用提供程序一起使用。通用提供程序是新版本的 sqlmembership 提供程序。这些基于 EF CodeFirst 并且还生成更清晰的数据库架构 查看我的以下帖子以获取更多详细信息 http://blogs.msdn.com/b/pranav_rastogi/archive/2012/09/12/integrate-openauth-openid-with-your-existing-asp-net-application-using-universal-providers.aspx

      【讨论】:

      • 通用提供者与 SimpleMembership 不兼容,这并不能解决 OP 的问题。
      【解决方案5】:

      这可能不适用于您的用例,但您当然可以非常轻松地将用户属性添加到 Simplemembership UserProfile 表中,而不是创建另一个用户表

      我建议使用现有的会员表来保存散列密码,而忽略不需要的字段。这样就无需大惊小怪地保持与 SimpleMembership 的兼容性。

      SQLMembership 非常容易开箱即用。我已经在几个项目中对 SQLMembership 进行了广泛的定制扩展,这并不难——但回头看,我希望我没有。维护起来有点麻烦,

      【讨论】:

        【解决方案6】:

        您可以通过扩展 MembershipProvider 创建自己的成员资格提供程序。有关详细信息,请参阅Custom MembershipProvider in .NET 4.0。使用这种方法,您只需要实现所需的方法。这应该有助于让事情变得更简单,并且不需要您添加不需要的表格。

        基本步骤(取自链接的 SO 答案)是:

        1. 创建一个新的 Class 文件(如果您不使用多层系统,请在项目的 Models 文件夹中)我们将其命名为 MyMembershipProvider.cs
        2. 从 System.Web.Security.MembershipProvider 继承该类
        3. 自动创建需要的方法(继承类中的句号+空格)

        【讨论】:

          【解决方案7】:

          您可以同时使用自定义用户表和 SimpleMembership 表。这种方法在过去对我很有效。

          例如,在 AccountController 的 Register 方法中,您可以通过将用户添加到自己的 Users 表中来注册新用户。然后使用您添加到 Users 表的用户的 Id 将此用户添加到 SimpleMembership UserProfile 表。

          using (var context = new MyDatabaseEntities())
          {
              User newUser = new User(){
                Name = model.Name,
                Email = model.Email,
                IsDeleted = false
              }
          
              // Add the user to your custom Users table
              context.Users.Add(newUser);
              context.SaveChanges();
          
              // Add this user to the SimpleMembership table using the same Id as the custom Users table
              WebSecurity.CreateUserAndAccount(newUser.Id.ToString(), model.Password);
          
              // Log the user in
              WebSecurity.Login(newUser.Id.ToString(), model.Password);
          }
          

          【讨论】:

            猜你喜欢
            • 2013-03-25
            • 2015-01-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-16
            • 2013-02-26
            相关资源
            最近更新 更多