如何将我自己的数据库与 SimpleMembership 和 WebSecurity 一起使用?啥是 MVC4 安全性?
Posted
技术标签:
【中文标题】如何将我自己的数据库与 SimpleMembership 和 WebSecurity 一起使用?啥是 MVC4 安全性?【英文标题】:How do I use my own database with SimpleMembership and WebSecurity? What is MVC4 security all about?如何将我自己的数据库与 SimpleMembership 和 WebSecurity 一起使用?什么是 MVC4 安全性? 【发布时间】:2013-05-18 05:32:19 【问题描述】:我已经阅读了我能找到的关于这个主题的所有内容,包括 MSDN 文章和 SO 帖子,但我仍然非常迷茫和困惑。
问题
请回答以下问题(如果可能,请简要回答):
SimpleMembership/SimpleMembershipProvider (WebMatrix.WebData) 是什么?他们负责/负责什么?
什么是WebSecurity (WebMatrix.WebData)?
什么是Membership(System.Web.Security)类?
为什么 MVC4 会创建 UserProfile 表和 webpages_Membership 表?它们有什么用,有什么区别? MVC4 创建的 UserProfile 类是什么?
什么是 UsersContext 类?
所有这些如何协同工作以进行用户身份验证?
我的情况
这些问题接着引出下一个问题:
假设我有一个包含用户(ID、用户名、密码)的现有数据库。我正在创建一个新的 MVC4 应用程序并使用表单身份验证。用户密码以加密形式(不是 bcrypt)存储在数据库中。
我必须做些什么才能使它与 MVC4 一起工作?
我必须创建一个自定义的MembershipProvider吗?
到目前为止我的知识
据我了解,WebSecurity 是一个与 MembershipProvider 交互的静态类(模块)。 MembershipProvider 是一个解释特定功能如何工作的类,例如 ValidateUser、CreateUser、ChangePassword。
为了解决我的问题,我假设我需要创建一个自定义 MembershipProvider 并告诉 WebSecurity 使用我的新 MembershipProvider。
赏金?
我已悬赏此问题,并打算将其奖励给 Andy Brown,以表彰其出色的回答。
【问题讨论】:
这是一个相当不受欢迎的观点,但我建议您远离 .Net 的内置安全模型。他们在允许 joe coder 创建安全网站方面令人困惑、效率低下且尝试不佳。在我看来,如果您不了解安全性的工作原理,则不应触摸它。此外,一旦发现任何 ASP.Net 安全设置的攻击向量,使用它的每个网站都容易受到攻击。如果您至少编写自己的代码,那么您将受益于它的漏洞利用没有在网络上被记录。了解如何创建安全网站并使用您自己的实现。 很有趣,我一定会更多地了解您的建议。谢谢。 目前,使用 SSL 进行登录和注册以及 SHAx 哈希以及密码盐将保护您免受最常见的问题。研究如何避免会话欺骗,您将获得基本网站会员资格所需的尽可能多的安全性。如果你正在处理信用卡,我建议你做更多的研究。 @SpencerRuport。我既不同意也不反对,但推出你自己的并不意味着它也是安全的,读者应该在这样做之前考虑他们的专业水平和时间。我的回答提到了开源安全论点的双方。 @Rowan。您的问题很大,至少由 9 个问题组成。我建议您阅读我对答案 1-6 的回答,提出一个新问题“我如何将现有的表与 SimpleMembership 一起使用”并从此处链接到它。没有人会读完这个问题的任何答案,因此它不会为 SO 用户创造价值。 【参考方案1】:请参阅每个引用下方的摘要以获得快速答案,并查看段落以获得详细信息。另请参阅最后的参考资料部分以获取权威来源。
总结
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类?
它是一个 DbContext
(DbContext API 的一部分),作为 MVC Internet 应用程序模板的启动提供。它唯一的工作是包含UserProfile
类,以便我们可以使用它(例如通过InitializeSimpleMembershipAttribute
)。
6.所有这些如何协同工作来进行用户身份验证?
现在从上面的摘要和下面的细节中应该可以看出这一点。使用:WebSecurity
用于常见任务; UserProfile
用于存储针对用户的自定义属性,通过 UsersContext
访问(在 Visual Studio“MVC Internet 应用程序”模板中); Membership
当WebSecurity
或OAuthWebSecurity
没有该方法时;和Roles
用于角色。使用 VS 模板的控制器查看使用示例。
编辑。万一有人走到这一步
假设我有一个现有的数据库...
如果您有一个现有的数据库,并且您编写自定义会员提供程序的唯一原因是处理您的旧密码存储方法,那么您可以使用一种解决方法。这只有在您可以从旧密码存储转移到 SimpleMembership 算法(使用 Rfc2898DeriveBytes
类)时才有效。详情见脚注。
如果您不能离开,那么是的,您将不得不创建自己的提供程序来使用您的特定密码算法,您可以这样做by deriving from SimpleMembershipProvider
。
注意:SimpleMembershipProvider
将 HASH your passwords not ENCRYPT them。如果您不知道区别以及为什么这很重要,那么在为您自己的提供商提供自定义安全性之前请三思而后行
详情
1.什么是SimpleMembership/SimpleMembershipProvider
要了解这一切如何结合在一起,有助于了解历史。
2005 年 ASP.NET introduced the ASP.NET Membership system 此系统使用提供程序从用于管理帐户和角色等的通用接口中抽象出实现细节。 它还为我们提供了基本的“用户配置文件”功能(存储在单列 xml 字段中,因此人们倾向于避免使用) SimpleMembership 于 2010 年发布,作为插入 ASP.NET 成员系统的提供程序,但也允许 OAuth 身份验证和按列属性存储用户配置文件(而不是使用的单列存储在原始实现中)。SimpleMembershipProvider
实现 ExtendedMembershipProvider
以扩展原始提供程序实现
它是开源的on codeplex(镜像on github)。因此,就安全性而言,您可以自己评估代码、克隆代码、更改代码等。您应该在open source security 的benefits and drawbacks 上选择your own view,然后用一小撮NIH 完成它。 (个人观点:我有时用,其他时候不用)
ExtendedMembershipProvider
本身将GeneratePasswordResetToken
之类的命令添加到旧的成员资格提供程序 api。
2.什么是WebSecurity(WebMatrix.WebData)?
WebSecurity
只是一个外观或辅助类,用于提供对SimpleMembershipProvider
的简单访问,并使常见任务在一个地方轻松访问。它既可以提供帮助,又因为通过ExtendedMembershipProvider
扩展原始框架意味着一些原始类(如Membership
)现在还不够。例子:
WebSecurity.CurrentUserName
- 获取当前登录用户的名字
WebSecurity.CreateUserAndAccount
。同时创建用户并设置用户配置文件属性(例如WebSecurity.CreateUserAndAccount(userName, pw, new Email = model.Email );
WebSecurity.InitializeDatabaseConnection
- 快速设置新的/现有的数据库以供会员使用,选择您的用户 ID 列和用户自然键标识符等。
ResetPassword
重置用户密码,GeneratePasswordResetToken
等等
这些方法通常取决于您正在使用的提供者,它们不仅仅依赖于 SimpleMembership,而且它们将诸如您的提供者和Membership
之类的对象绑定在一起,以提供一个共同点来做会员功能。
请注意,还有 OAuthWebSecurity
,它相当于用于 OAuth 身份验证的 WebSecurity
。
3.什么是Membership(System.Web.Security)类?
Membership
来自原始实现;它使用ExtendedMembershipProvider
现在扩展的基本MembershipProvider
实现来管理用户设置并执行与用户相关的操作。它是一个静态类,因此在您声明命名空间的任何地方都可用,因此是一种简单的方法,例如,检索当前用户: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
表由UsersContext
中的UserProfile
类表示(如果您使用默认的MVC Internet 应用程序模板)。因此,我们通过与 DbContext
中包含的任何类一起使用的常用方法来访问它。
UserProfile
对代码优先非常友好:您可以添加列(例如用户的Email
地址),然后设置迁移以在您的下一个版本中将该列包含在数据库中(如果您喜欢使用迁移)。事实上,UserProfile
表不必这样调用 - 您可以使用 WebSecurity.InitializeDatabaseConnection
调用、[Table("UserProfile")] public class UserProfile
和您自己的迁移来更改它。
5.什么是UsersContext类?
这是来自 Visual Studio 新项目中提供的 MVC Internet 应用程序模板。我要做的第一件事是确保它与我自己的数据库上下文共享一个公共连接字符串(假设成员表在同一个数据库中)。如果需要,您可以更改它并在以后将它们解耦。
您不需要将其与您自己的上下文分开 - 仅当您现在或将来想将会员信息存储在不同的数据库中时才需要这样做 如果您摆脱它,您只需更改对 @ 的引用987654424@ 适应您自己的上下文,调整Database.SetInitializer
。
参考资料:
Using SimpleMembership With ASP.NET WebPages - Matthew Osborn - 这是关于 SimpleMembership 的原始参考资料,以及它是什么、为什么是以及它的作用:
MSDN - Introduction to Membership - 会员制仍然是 SimpleMembership 的核心,因此有助于了解它。
codeplex source(镜像on github)。WebSecurity
OAuthWebSecurity
SimpleMembershipProvider
ExtendedMembershipProvider
SimpleRoleProvider
Membership
Roles
DbContext
和 DbContext API
编辑脚注:进行滚动密码升级的细节
向UserProfile
添加一个属性,该属性存储帐户使用的密码版本(例如,1 代表旧版,2 代表 SimpleMembership)
在“登录”操作中,编写代码以便:
如果他们在您的 SimpleMembership 密码版本上,您可以正常登录
如果他们使用旧密码版本,您:
使用旧方法检查
如果正确,请使用 ResetPassword
重置它,然后使用 ChangePassword
以使用 SimpleMembership 版本,这会将字段更新为新密码版本
最后更新UserProfile
上的密码版本
更新任何其他以类似方式使用密码的 AccountsController 方法。
使用 hacky 解决方法并与 webpages_Membership
表耦合,因为您不必编写新的自定义提供程序。
可以使用TransactionScope
使所有这些事务化。唯一令人讨厌的是控制器中的额外代码,以及与webpages_Membership
的耦合。
【讨论】:
很好的答案。希望更多人看到。 像我这样的人,他们正是需要这些信息,而这里的布局都很好。谢谢以上是关于如何将我自己的数据库与 SimpleMembership 和 WebSecurity 一起使用?啥是 MVC4 安全性?的主要内容,如果未能解决你的问题,请参考以下文章
将我的应用程序与 iPhone 4G 的 Nike+ 功能集成的最佳选择