我已经阅读了有关此主题的所有内容,包括MSDN文章和SO帖子,但我仍然非常迷茫和困惑。
请回答以下问题(如果可能,请简要回答):
什么是 SimpleMembership / SimpleMembershipProvider ( WebMatrix.WebData )以及它们负责的是什么?
什么是 WebSecurity ( WebMatrix.WebData )?
什么是会员( System.Web.Security )类?
为什么MVC4会创建 UserProfile 表和 webpages_Membership 表?它们是什么,有什么区别? MVC4创建的UserProfile类是什么?
什么是 UsersContext 类?
所有这些如何协同工作以进行用户身份验证?
这些问题会导致下一个问题:
假设我有一个包含用户的现有数据库(ID,用户名,密码)。我正在创建一个新的MVC4应用程序并使用表单身份验证。用户密码以加密形式(不是bcrypt)存储在数据库中。
如何使其与MVC4一起使用?
我是否必须创建自定义 MembershipProvider ?
据我所知, WebSecurity 是一个与 MembershipProvider 交互的静态类(Module)。 MembershipProvider是一个解释特定函数如何工作的类,例如 ValidateUser , CreateUser , ChangePassword 。
为了解决我的问题,我假设我需要创建一个自定义MembershipProvider并告诉WebSecurity使用我的新MembershipProvider。
我已经在这个问题上获得了赏金,并打算将其授予安迪·布朗,以获得出色的答案。
答案 0 :(得分:183)
请参阅下面的摘要以获得快速回答,以及详细的段落。另请参阅最后的参考文献部分,了解权威来源。
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 Application模板的开头提供。它唯一的工作是包含UserProfile
类,以便我们可以使用它(例如通过InitializeSimpleMembershipAttribute
)。
6.所有这些如何协同工作以进行用户身份验证?
现在可以从上面的摘要和下面的详细信息中看出这一点。使用:WebSecurity
执行常见任务; UserProfile
用于存储针对用户的自定义属性,可通过UsersContext
(在Visual Studio" MVC Internet Application"模板中)访问;当Membership
或WebSecurity
没有方法时,OAuthWebSecurity
;和Roles
角色。使用VS模板的控制器查看使用示例。
修改即可。如果有人到目前为止
假设我有一个现有的数据库......
如果您有现有数据库,并且编写自定义成员资格提供程序的唯一原因是处理旧密码存储方法,则可以使用变通方法。这只有在您可以从旧密码存储转移到SimpleMembership算法(使用Rfc2898DeriveBytes
类)时才有效。有关详细信息,请参阅脚注。
如果您无法离开,那么您将需要创建自己的提供商以使用您的特定密码算法,您可以by deriving from SimpleMembershipProvider
。
注意:SimpleMembershipProvider
将HASH your passwords not ENCRYPT them。如果你不知道差异以及为什么这很重要,那么在使用自定义安全性做自己的提供者之前要三思而后
要了解它们如何组合在一起,有助于理解历史。
SimpleMembershipProvider
实施ExtendedMembershipProvider
以扩展原始提供商实施它是开源on codeplex(镜像on github)。就安全性而言,您可以自己评估代码,克隆代码,更改代码等。您应该your own view benefits and drawbacks open source security,然后用捏NIH。 (个人观点:我有时使用它,我不会在其他时间使用它)
ExtendedMembershipProvider
本身会将GeneratePasswordResetToken
等命令添加到旧的成员资格提供程序apis中。
WebSecurity
只是一个Facade或helper类,可以提供对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
相当。
Membership
来自最初的实施;它使用MembershipProvider
现在扩展的基本ExtendedMembershipProvider
实现来管理用户设置并执行与用户相关的操作。它是一个静态类,因此可以在声明命名空间的任何地方使用,因此可以轻松地检索当前用户:Membership.GetUser
WebSecurity
执行某些事情而不是其他事情,导致混淆,而Membership
执行某些操作而不执行其他操作。如果您将WebSecurity
视为更高级别操作的工具包,并将Membership
视为向用户执行操作的工具包,那么您就可以了;他们在您的提供商上一起工作。
webpages_Membership
是一个具有固定架构的表,我们单独留下,并允许提供商执行基本帐户操作,主要是存储凭据。UserProfile
是我们自定义的表格,用于存储针对用户帐户的信息,并通过UserProfile
类以强类型格式提供。 webpages_OAuthMembership
的额外表,与webpages_Membership
执行相同的工作,但对于要与之集成的OAuth登录提供程序。此设置的神奇之处在于,单个用户可以在您自己的网站上拥有会员登录权限,并且具有不同提供商(如google,facebook)的任意数量的OAuth登录都会共享存储在{{1}中的常用个人资料}
通常,如果表格以UserProfile
开头,则表示有一个API可以访问它。 webpages_
表由UserProfile
中的UserProfile
类表示(如果使用默认的MVC Internet应用程序模板)。因此,我们通过我们将使用UsersContext
中包含的任何类的常用方法来访问它。
DbContext
对代码优先非常友好:您可以添加列(例如用户的UserProfile
地址),然后设置迁移以在您的数据库中包含该列下一个版本(如果您喜欢使用迁移)。实际上,不必调用Email
表 - 您可以使用UserProfile
调用,WebSecurity.InitializeDatabaseConnection
和您自己的迁移来更改它。
这是来自Visual Studio New Project中提供的MVC Internet Application模板。我要做的第一件事是确保它与我自己的数据库上下文共享一个公共连接字符串(假设成员资格表在同一个数据库中)。如果需要,您可以更改此设置并稍后将其解耦。
您不需要将它与您自己的上下文分开 - 只有当您想要在现在或将来将成员资格信息存储在不同的数据库中时才有必要如果您将其删除,您只需更改参考文献根据您自己的情况调整[Table("UserProfile")] public class UserProfile
,调整UsersContext
。
<强>参考文献:强>
Using SimpleMembership With ASP.NET WebPages - Matthew Osborn - 这是关于SimpleMembership的原始参考资料及其内容,原因以及它的作用:
MSDN - Introduction to Membership - 成员资格仍然是SimpleMembership的核心,因此有助于理解它。
WebSecurity
OAuthWebSecurity
SimpleMembershipProvider
ExtendedMembershipProvider
SimpleRoleProvider
Membership
Roles
DbContext
和DbContext API 编辑脚注:滚动密码升级的详细信息
Database.SetInitializer
添加一个属性,该属性存储该帐户所使用的密码版本(例如,1表示遗留,2表示SimpleMembership)UserProfile
然后ResetPassword
重置它以使用SimpleMembership版本,这会将字段更新为新密码版本ChangePassword
UserProfile
表格相关联,我们并不打算触摸,因为您不必编写新的自定义提供程序。可以使用TransactionScope
进行所有此交易。唯一令人讨厌的事情是控制器中的额外代码,以及与webpages_Membership
的耦合。