如何使用自己的数据库与SimpleMembership和WebSecurity?什么是MVC4安全性?

61
我已阅读了所有相关的内容,包括 MSDN 文章和 SO 帖子,但我仍然很迷惑和困惑。
问题:
1. 什么是 SimpleMembership/SimpleMembershipProvider(WebMatrix.WebData),它们的职责是什么?
2. 什么是 WebSecurity(WebMatrix.WebData)?
3. Membership(System.Web.Security) 类是什么?
4. 为什么 MVC4 创建了 UserProfile 表和 webpages_Membership 表?它们是用来做什么的?UserProfile 类是什么?
5. UsersContext 类是什么?
6. 这些如何一起工作以实现用户身份验证?
我的情况:
这些问题导致了下一个问题:
假设我有一个带有用户(ID、用户名、密码)的现有数据库。我正在创建一个新的 MVC4 应用程序,并使用表单身份验证。用户密码以加密形式存储在数据库中(不是 bcrypt)。
我需要做什么才能让它与 MVC4 正常工作?
我需要创建自定义 MembershipProvider 吗?
我的知识:
据我理解,WebSecurity 是一个静态类(模块),用于与 MembershipProvider 交互。MembershipProvider 是一个类,它解释了特定函数的工作原理,如 ValidateUser、CreateUser、ChangePassword 等。
为了解决我的问题,我认为我需要创建自定义 MembershipProvider,并告诉 WebSecurity 使用我的新 MembershipProvider。
悬赏?
我在这个问题上放了一个悬赏,并打算授予 Andy Brown 杰出的答案。

4
这是一个不太受欢迎的观点,但我建议你远离.Net的内置安全模型。它们令人困惑、效率低下,并且是让普通程序员创建安全网站的失败尝试。我认为,如果你不理解安全工作原理,就不应该去碰它。此外,一旦发现针对任何ASP.Net安全设置的攻击向量,使用它的每个网站都会变得容易受到攻击。如果你自己编写代码,就至少可以避免它被记录在网上的漏洞被用于攻击。学习如何创建安全的网站并使用自己的实现。 - Spencer Ruport
目前,使用SSL进行登录和注册以及SHAx哈希加上密码盐将保护您免受最常见的安全问题。研究如何避免会话欺骗,您将拥有基本网站会员所需的足够安全性。如果您处理信用卡,我建议您进行更多的研究。 - Spencer Ruport
2
@SpencerRuport。我既不同意也不反对,但自己编写代码并不意味着它一定会安全,读者在决定之前应该考虑自己的专业水平和时间。我的回答中提到了开源安全争论的双方观点。 - Andy Brown
1
@Rowan。你的问题很大,至少包含九个问题。我建议您阅读我的回答以获取1-6的答案,为“如何使用现有表与SimpleMembership”提出新问题,并从这里链接到它。没有人会阅读完这个问题的任何答案,因此它不会为SO用户创造价值。 - Andy Brown
@RowanFreeman。你在数据库中提到了_加密_密码。我已经在我的回答中添加了有关哈希和加密之间区别的编辑。如果你不确定这个区别以及为什么它很重要,那么在自己开发安全性之前应该仔细考虑。 - Andy Brown
显示剩余2条评论
1个回答

189

请看每个引语下面的摘要以获取快速答案,以及详细信息的段落。还可以在末尾的参考文献部分查看权威来源。

摘要

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

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

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

WebSecurity 是一个辅助类,用于常见的成员资格任务,与 OAuthWebSecurityMembership 一起使用。角色仍然通过 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 Application"模板中);当WebSecurityOAuthWebSecurity没有该方法时,使用Membership;用于角色的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,它相当于OAuth身份验证的WebSecurity
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登录,并且它们都共享存储在中的公共配置文件。
通常,如果一个表以开头,那么就表示有一个API可以访问它。在您的中,表由类表示(如果您使用默认的MVC Internet应用程序模板)。因此,我们通过与任何包含在中的类一起使用的通常方法来访问它。 非常适合代码优先:您可以添加列(例如用户的地址),然后设置迁移,以便在下一个发布中将该列包含在您的数据库中(如果您喜欢使用迁移)。实际上,表不必被称为那个名字 - 您可以使用调用、[Table("UserProfile")] public class UserProfile和您自己的迁移来更改它。
5.什么是类?
这是在Visual Studio新项目中提供的MVC Internet应用程序模板。我首先要做的是确保它与我的数据库上下文共享一个常见的连接字符串(假设成员资格表在同一个数据库中)。如果您想要在现在或将来将成员资格信息存储在不同的数据库中,则可以稍后更改此设置并使其解耦。
您不需要将其分开到自己的上下文中 - 只有在您想要立即或将来将成员身份信息存储在不同的数据库中时才需要这样做。如果您将其删除,只需更改对UsersContext的引用以及调整Database.SetInitializer即可。
参考资料: - 使用SimpleMembership与ASP.NET WebPages - Matthew Osborn - 这是关于SimpleMembership的原始参考资料,介绍了它是什么、为什么以及它的功能。 - MSDN - 成员身份简介 - 成员身份仍然是SimpleMembership的核心,因此了解一些相关知识会很有帮助。

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

  • UserProfile 添加一个属性,用于存储帐户所在的密码版本(例如,遗留版为1,SimpleMembership版为2)
  • 在“登录”操作中,编写代码:
    • 如果他们使用的是 SimpleMembership 版本的密码,则进行正常登录
    • 如果他们使用的是遗留版密码,则:
      • 使用旧方法进行检查
      • 如果正确,则使用 ResetPassword 然后使用 ChangePassword 重置密码以使用 SimpleMembership 版本,这将更新字段到新的密码版本
      • 最后更新 UserProfile 上的密码版本
  • 以类似方式更新任何其他使用密码的 AccountsController 方法。
  • 与我们不应该触及的 webpages_Membership 表的 hacky workaround 和耦合一起运行,因为您不必编写新的自定义提供程序。

使用 TransactionScope 可以使所有事务具有事务性。唯一令人讨厌的是控制器中额外的代码和对 webpages_Membership 的耦合。


2
很棒的答案。我希望更多的人能看到它。 - Rowan Freeman
1
像我这样需要这些信息的人,现在它们都被很好地呈现出来了。谢谢。 - J Benjamin
1
@andy-brown 很好的回答。第三方链接显示它们的年龄(以死链接的形式)。由于这些参考链接现在有点过时,而且没有足够的空间在回复中发布我的补充说明,我制作了一个单独的答案来包含这些更新...谁知道十年后还会有人需要这些信息,但是我在这里。请随意使用其中任何内容来增强此内容或与您的完整答案并存。我还没有走出这个“坑”。我将其视为一份活文档,直到系统更新完成。 - Hunter-Orionnoir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接