62

我已经阅读了我能找到的关于这个主题的所有内容,包括 MSDN 文章和 SO 帖子,但我仍然非常迷茫和困惑。

问题

请回答以下问题(如果可能,请简要回答):

  1. 什么是SimpleMembership/SimpleMembershipProvider ( WebMatrix.WebData ),它/他们负责什么?

  2. 什么是WebSecurity ( WebMatrix.WebData )?

  3. 什么是Membership ( System.Web.Security ) 类?

  4. 为什么 MVC4 会创建一个UserProfile表和一个pages_Membership表?它们有什么用,有什么区别?MVC4 创建的 UserProfile 类是什么?

  5. 什么是UsersContext类?

  6. 所有这些如何协同工作以进行用户身份验证?

我的情况

然后这些问题导致下一个问题:

假设我有一个包含用户(ID、用户名、密码)的现有数据库。我正在创建一个新的 MVC4 应用程序并使用表单身份验证。用户密码以加密形式(不是 bcrypt)存储在数据库中。

我必须做些什么才能使它与 MVC4 一起工作?

我是否必须创建自定义MembershipProvider

到目前为止我的知识

据我了解,WebSecurity是一个与MembershipProvider交互的静态类(模块) 。MembershipProvider 是一个解释特定功能如何工作的类,例如ValidateUserCreateUserChangePassword

为了解决我的问题,我假设我需要创建一个自定义 MembershipProvider 并告诉 WebSecurity 使用我的新 MembershipProvider。

赏金?

我已经悬赏了这个问题,并打算将其奖励给 Andy Brown,以表彰其出色的答案。

4

1 回答 1

188

请参阅每个报价下方的摘要以获取快速答案,并查看段落以获取详细信息。另请参阅最后的参考资料部分以获取权威来源。

总结

1.什么是SimpleMembership/SimpleMembershipProvider (WebMatrix.WebData),它/他们负责什么?

SimpleMembership(一个涵盖SimpleMembershipProvider和的术语SimpleRoleProvider)负责提供一种简洁快捷的方式来实现一个 80% 即插即用的身份验证和授权框架,该框架具有安全的密码存储,任何人都可以使用。

2.什么是WebSecurity(WebMatrix.WebData)?

WebSecurity是与Membership和一起工作的常见成员任务的助手类OAuthWebSecurity。角色仍然可以通过Roles.

3.什么是Membership(System.Web.Security)类?

Membership是管理用户设置和操作的原始 ASP.NET 成员实现的静态类。许多用户操作仍然在这里完成,而不是在WebSecurity. 他们都使用您选择的同一提供商。

4.MVC4为什么要创建UserProfile表和webpages_Membership表?它们有什么用,有什么区别?MVC4 创建的 UserProfile 类是什么?

这两个表执行不同的功能。架构由webpages_Membership框架控制并用于凭据,UserProfile架构由我们控制并用于我们要针对用户存储的任何属性。

5.什么是UsersContext类?

它是一个DbContextDbContext API的一部分),作为 MVC Internet 应用程序模板的启动提供。它唯一的工作是包含UserProfile类,以便我们可以使用它(例如通过InitializeSimpleMembershipAttribute)。

6.所有这些如何协同工作来进行用户身份验证?

现在从上面的总结和下面的细节中应该可以看出这一点。用途:WebSecurity用于常见任务;UserProfile用于存储针对用户的自定义属性,通过UsersContext(在 Visual Studio“MVC Internet 应用程序”模板中)访问;Membership何时WebSecurityOAuthWebSecurity没有该方法;和Roles角色。使用 VS 模板的控制器查看使用示例。

编辑. 万一有人走到这一步

假设我有一个现有的数据库......

如果您有一个现有的数据库,并且您编写自定义会员提供程序的唯一原因是处理您的旧密码存储方法,那么您可以使用一种解决方法。这只有在您可以从旧密码存储转移到 SimpleMembership 算法(使用Rfc2898DeriveBytes该类)时才有效。详情见脚注。

如果您不能离开,那么是的,您将不得不创建自己的提供程序来使用您的特定密码算法,您可以通过从SimpleMembershipProvider.

注意:SimpleMembershipProvider散列您的密码而不是对其进行加密。如果您不知道区别以及为什么这很重要,那么在为您自己的提供商提供自定义安全之前请三思而后行


细节

1.什么是SimpleMembership/SimpleMembershipProvider

要了解这一切如何结合在一起,有助于了解历史。

  • ASP.NET 于 2005 年引入了 ASP.NET Membership 系统
  • 该系统使用提供者从用于管理帐户和角色等的通用接口中抽象出实现细节。
  • 它还为我们提供了基本的“用户配置文件”功能(存储在单列 xml 字段中,因此人们倾向于避免使用)
  • SimpleMembership 于 2010 年发布,作为一个插入 ASP.NET 会员系统的提供程序,但也允许 OAuth 身份验证和按列属性存储用户配置文件(而不是原始中使用的单列存储)执行)。
  • SimpleMembershipProvider实现ExtendedMembershipProvider扩展原始提供程序实现

它是codeplex上的开源代码(镜像在 github 上)。因此,就安全性而言,您可以自己评估代码、克隆代码、更改代码等。您应该对开源安全性的利弊自己的看法,并通过一些NIH来解决这个问题。(个人观点:有时用,其他时候不用

ExtendedMembershipProvider本身添加了类似于GeneratePasswordResetToken旧会员提供程序 api 的命令。

2.什么是WebSecurity(WebMatrix.WebData)?

WebSecurity只是一个外观或帮助类,用于提供SimpleMembershipProvider对一个地方的简单访问并使常见任务易于访问。它既可以提供帮助,也因为原始框架的扩展ExtendedMembershipProvider意味着一些原始类Membership现在还不够。例子:

这些方法通常取决于您正在使用的提供者,它们不仅仅依赖于 SimpleMembership,而且它们将像您的提供者这样的对象联系在一起,并Membership提供一个共同点来执行成员资格功能。

请注意,OAuthWebSecurity这也相当于WebSecurityOAuth 身份验证。

3.什么是Membership(System.Web.Security)类?

Membership来自原始实现;它使用现在扩展的基本MembershipProvider实现来管理用户设置并执行与用户相关的操作。ExtendedMembershipProvider它是一个静态类,因此在您声明命名空间的任何地方都可用,因此是一种简单的方法,例如,检索当前用户:Membership.GetUser

WebSecurity做一些事情而不做其他事情,做一些事情而不做其他事情会造成混乱Membership。如果您将WebSecurity其视为用于更高级别操作的工具包,并且Membership将其视为对用户做事的工具包,那么您会没事的;他们一起为您的提供商工作。

4.MVC4为什么要创建UserProfile表和webpages_Membership表?它们有什么用,有什么区别?MVC4 创建的 UserProfile 类是什么?

  • webpages_Membership是一个具有固定模式的表,我们不理会它,它允许提供者进行基本的帐户操作,主要是存储凭据。
  • UserProfile是我们定制的用于存储针对用户帐户的信息的表,并通过UserProfile该类以强类型格式提供。
  • 有一个名为的额外表webpages_OAuthMembership与 执行相同的工作webpages_Membership,但用于您想要集成的 OAuth 登录提供程序。

这种设置的神奇之处在于,单个用户可以在您自己的网站上进行会员登录,并且可以通过不同的提供商(如 google、facebook)进行任意数量的 OAuth 登录,并且它们都共享一个存储在UserProfile

通常,如果一个表以 开头webpages_,则意味着有一个 API 可以访问它。该UserProfile表由UserProfile您的类表示UsersContext(如果您使用默认的 MVC Internet 应用程序模板)。因此,我们通过对包含在 a 中的任何类使用的常用方法来访问它DbContext

UserProfile非常友好的代码优先:您可以添加列(例如用户的Email地址),然后设置迁移以在您的下一个版本中将该列包含在您的数据库中(如果您喜欢使用迁移)。实际上,UserProfile不必这样调用该表 - 您可以使用WebSecurity.InitializeDatabaseConnection调用[Table("UserProfile")] public class UserProfile、 和您自己的迁移来更改它。

5.什么是UsersContext类?

这来自 Visual Studio 新项目中提供的 MVC Internet 应用程序模板。我要做的第一件事是确保它与我自己的数据库上下文共享一个公共连接字符串(假设成员表在同一个数据库中)。如果需要,您可以更改它并在以后将它们解耦。

您不需要将其与您自己的上下文分开 - 仅当您现在或将来想将成员信息存储在不同的数据库中时才需要这样做 如果您摆脱它,您只需将引用更改UsersContext为您自己的上下文, 调整Database.SetInitializer.

参考:

Using SimpleMembership With ASP.NET WebPages - Matthew Osborn - 这是关于 SimpleMembership 的原始参考资料,以及它是什么、为什么是以及它的作用:

MSDN - Introduction to Membership - Membership 仍然是 SimpleMembership 的核心,因此对它有所了解会有所帮助。


编辑脚注:进行滚动密码升级的详细信息

  • 添加一个属性来UserProfile存储帐户所使用的密码版本(例如,1 代表旧版,2 代表 SimpleMembership)
  • 在“登录”操作中,编写代码以便:
    • 如果他们在您的 SimpleMembership 密码版本上,您可以正常登录
    • 如果他们在旧密码版本上,您:
      • 使用您的旧方法进行检查
      • 如果正确,您使用ResetPasswordthen重置它ChangePassword以使用 SimpleMembership 版本,这会将字段更新为新密码版本
      • 最后更新密码版本UserProfile
  • 以类似方式更新任何其他使用密码的 AccountsController 方法。
  • 使用 hacky 解决方法并耦合到webpages_Membership我们不打算触摸的表,因为您不必编写新的自定义提供程序。

可以使用TransactionScope. 唯一令人讨厌的事情是控制器中的额外代码,以及与webpages_Membership.

于 2013-05-24T12:10:15.417 回答