在 SQL Server 中创建成员身份架构 (VB)
注意
自本文撰写以来,ASP.NET 成员身份提供程序已被 ASP.NET Identity取代。 我们强烈建议更新应用以使用 ASP.NET Identity 平台,而不是在本文撰写时使用的成员身份提供程序。 ASP.NET 标识在 ASP.NET 成员身份系统中具有许多优势,包括:
- 性能更佳
- 改进了可扩展性和可测试性
- 支持 OAuth、OpenID Connect 和双因素身份验证
- 基于声明的标识支持
- 与 ASP.Net Core 的互操作性更好
本教程首先介绍将必要的架构添加到数据库中的技术,以便使用 SqlMembershipProvider。 接下来,我们将检查架构中的键表,并讨论其用途和重要性。 本教程最后介绍如何告诉 ASP.NET 应用程序成员身份框架应使用哪个提供程序。
介绍
前面的两个教程使用表单身份验证来识别网站访问者。 表单身份验证框架使开发人员可以轻松地将用户登录到网站,并通过使用身份验证票证在页面访问中记住这些用户。 FormsAuthentication
类包括用于生成票证并将其添加到访问者的 Cookie 中的方法。 FormsAuthenticationModule
检查所有传入的请求,对于具有有效身份验证票证的请求,创建 GenericPrincipal
和 FormsIdentity
对象,并将它们与当前请求相关联。 表单身份验证只是一种机制,用于在登录时向访问者授予身份验证票证,并在后续请求中分析该票证以确定用户的标识。 对于支持用户帐户的 Web 应用程序,我们仍需要实现用户存储并添加功能来验证凭据、注册新用户以及大量其他用户帐户相关任务。
在 ASP.NET 2.0 之前,开发人员需要负责实现所有这些与用户帐户相关的任务。 幸运的是,ASP.NET 团队认识到了这一缺点,并引入了 ASP.NET 2.0 的成员资格框架。 成员资格框架是 .NET Framework 中的一组类,提供用于完成核心用户帐户相关任务的编程界面。 此框架构建在 提供程序模型之上,使开发人员能够将自定义实现插入标准化 API。
如 安全基础知识和 ASP.NET 支持 教程中所述,.NET Framework 附带两个内置成员身份提供程序:ActiveDirectoryMembershipProvider
和 SqlMembershipProvider
。 顾名思义,SqlMembershipProvider
使用Microsoft SQL Server 数据库作为用户存储。 为了在应用程序中使用这个提供程序,我们需要告诉提供程序哪个数据库用作存储。 正如你想象的那样,SqlMembershipProvider
希望用户存储数据库具有某些数据库表、视图和存储过程。 我们需要将此预期的架构添加到所选数据库。
本教程首先探讨将所需架构添加到数据库以便使用 SqlMembershipProvider
的技术。 接下来,我们将检查架构中的键表,并讨论其用途和重要性。 本教程最后介绍如何告诉 ASP.NET 应用程序成员身份框架应使用哪个提供程序。
让我们开始吧!
步骤 1:确定用户存储库的位置
ASP.NET 应用程序的数据通常存储在数据库中的多个表中。 实现 SqlMembershipProvider
数据库架构时,必须决定是否将成员资格架构放置在与应用程序数据相同的数据库中,还是放置在备用数据库中。
出于以下原因,建议将成员资格架构定位到与应用程序数据相同的数据库中:
- 可维护性 其数据封装在一个数据库中的应用程序比具有两个单独的数据库的应用程序更容易理解、维护和部署。
- 关系完整性,通过将与成员身份相关的表放置在与应用程序表相同的数据库中,可以在与成员身份相关的表和相关应用程序表中的主键之间建立 外键约束。
如果有多个应用程序使用单独的数据库,但需要共享通用用户存储,则仅可将用户存储和应用程序数据分离为单独的数据库才有意义。
创建数据库
我们从第二个教程开始构建的应用程序至今尚未需要数据库。 我们现在需要一个用于用户商店的。 让我们创建一个,然后将 SqlMembershipProvider
提供程序所需的模式添加到其中(请参阅步骤 2)。
注意
在本系列教程中,我们将使用 Microsoft SQL Server 2005 Express Edition 数据库来存储应用程序表和 SqlMembershipProvider
架构。 这一决定是由两个原因做出的:第一,由于成本 -- 免费 - Express Edition 是 SQL Server 2005 最易读的可访问版本;其次,可以将 SQL Server 2005 Express Edition 数据库直接放置在 Web 应用程序的 App_Data
文件夹中,使其成为将数据库和 Web 应用程序打包在一个 ZIP 文件中并重新部署数据库,而无需任何特殊的设置说明或配置选项。 如果首选使用非 Express Edition 版本的 SQL Server 进行学习,敬请遵循本心。 这些步骤几乎完全相同。 SqlMembershipProvider
架构将适用于任何版本的 Microsoft SQL Server 2000 及更新。
在解决方案资源管理器中,右键单击 App_Data
文件夹,然后选择“添加新项”。 (如果在项目中看不到 App_Data
文件夹,请在解决方案资源管理器中右键单击项目,选择“添加 ASP.NET 文件夹”,然后选择 App_Data
。在“添加新项”对话框中,选择添加名为 SecurityTutorials.mdf
的新 SQL 数据库。 在本教程中,我们将 SqlMembershipProvider
架构添加到此数据库;在后续教程中,我们将创建其他表来捕获应用程序数据。
图 1:将名为 SecurityTutorials.mdf
数据库的新 SQL 数据库添加到 App_Data
文件夹(单击以查看全尺寸图像)
将数据库添加到 App_Data
文件夹中会自动将其包含在“数据库资源管理器”视图中。 (在 Visual Studio 的非 Express Edition 版本中,数据库资源管理器称为服务器资源管理器。)转到数据库资源管理器,并展开刚刚添加的 SecurityTutorials
数据库。 如果未在屏幕上看到“数据库资源管理器”,请转到“视图”菜单并选择“数据库资源管理器”,或按 Ctrl+Alt+S。 如图 2 所示,SecurityTutorials
数据库为空 - 它不包含表、无视图和存储过程。
图 2:SecurityTutorials
数据库当前为空(单击以查看全尺寸图像)
步骤 2:将SqlMembershipProvider
架构添加到数据库
SqlMembershipProvider
要求在用户存储数据库中安装一组特定的表、视图和存储过程。 可以使用 aspnet_regsql.exe
工具添加这些必备数据库对象。 此文件位于 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\
文件夹中。
注意
aspnet_regsql.exe
工具提供命令行功能和图形用户界面。 图形界面更加用户友好,我们将在本教程中对其进行介绍。 当需要自动添加 SqlMembershipProvider
架构时,命令行接口非常有用,例如在生成脚本或自动测试方案中。
aspnet_regsql.exe
工具用于向指定的 SQL Server 数据库添加或删除 ASP.NET 应用程序服务。 ASP.NET 应用程序服务包含 SqlMembershipProvider
和 SqlRoleProvider
的架构,以及其他 ASP.NET 2.0 框架的基于 SQL 的提供程序的架构。 我们需要向 aspnet_regsql.exe
工具提供两条信息:
- 我们是否要添加或删除应用程序服务,以及
- 用于添加或删除应用程序服务架构的数据库
在提示数据库使用时,aspnet_regsql.exe
工具要求我们提供数据库所在的服务器的名称、连接到数据库的安全凭据以及数据库名称。 如果您使用的不是 SQL Server Express Edition,那么您应该已经了解这条信息,因为这与您通过 ASP.NET 网页与数据库交互时必须通过连接字符串提供的信息是相同的。 但是,在 App_Data
文件夹中使用 SQL Server 2005 Express Edition 数据库时,确定服务器和数据库名称会更加复杂。
以下部分介绍在 App_Data
文件夹中为 SQL Server 2005 Express Edition 数据库指定服务器和数据库名称的简单方法。 如果不使用 SQL Server 2005 Express Edition,可以跳到“安装应用程序服务”部分。
确定App_Data
文件夹中 SQL Server 2005 Express Edition 数据库的服务器和数据库名称
若要使用 aspnet_regsql.exe
工具,我们需要知道服务器和数据库名称。 服务器名称 localhost\InstanceName
。 最有可能的是,InstanceName 是 SQLExpress
。 但是,如果手动安装了 SQL Server 2005 Express Edition(也就是说,在安装 Visual Studio 时未自动安装它),则可以选择其他实例名称。
要确定数据库名称有点棘手。 App_Data
文件夹中的数据库通常具有一个数据库名称,其中包含 全局唯一标识符 以及数据库文件的路径。 我们需要确定此数据库名称,以便通过 aspnet_regsql.exe
添加应用程序服务架构。
确定数据库名称的最简单方法是通过 SQL Server Management Studio 对其进行检查。 SQL Server Management Studio 提供了用于管理 SQL Server 2005 数据库的图形界面,但它不随 SQL Server 2005 Express Edition 一起提供。 好消息是,你可以下载免费的 SQL Server Management Studio Express 版。
注意
如果桌面上还安装了非 Express Edition 版本的 SQL Server 2005,则可能会安装完整的 Management Studio 版本。 可以使用完整版本来确定数据库名称,按照Express版本下概述的相同步骤操作。
首先关闭 Visual Studio,以确保 Visual Studio 对数据库文件施加的任何锁都已关闭。 接下来,启动 SQL Server Management Studio 并连接到 SQL Server 2005 Express Edition localhost\InstanceName
数据库。 如前所述,实例名称很可能是 SQLExpress
。 对于“身份验证”选项,请选择“Windows 身份验证”。
图 3:连接到 SQL Server 2005 Express Edition 实例(单击可查看全尺寸图像)
连接到 SQL Server 2005 Express Edition 实例后,Management Studio 会显示数据库、安全设置、服务器对象等的文件夹。 如果展开“数据库”选项卡,将看到 SecurityTutorials.mdf
数据库未在数据库实例中注册,因此我们需要先附加数据库。
右键单击“数据库”文件夹,然后从上下文菜单中选择“附加”。 此时将显示“附加数据库”对话框。 在此处,单击“添加”按钮,浏览到 SecurityTutorials.mdf
数据库,然后单击“确定”。 图 4 显示了选中 SecurityTutorials.mdf
数据库后“附加数据库”对话框。 图 5 显示成功附加数据库后 Management Studio 的对象资源管理器。
图 4:附加 SecurityTutorials.mdf
数据库(单击以查看完整大小的图像)
图 5:SecurityTutorials.mdf
数据库显示在“数据库”文件夹中(单击以查看全尺寸图像)
如图 5 所示,SecurityTutorials.mdf
数据库的名称相当荒谬。 让我们将其更改为一个更难忘的(和更容易键入)的名称。 右键单击数据库,从上下文菜单中选择“重命名”,并将其重命名为 SecurityTutorialsDatabase
。 这不会更改文件名,而仅会更改数据库用于向 SQL Server 标识自身的名称。
图 6:将数据库重命名为 SecurityTutorialsDatabase
(单击以查看全尺寸图像)
此时,我们分别知道 SecurityTutorials.mdf
数据库文件的服务器和数据库名称:localhost\InstanceName
和 SecurityTutorialsDatabase
。 现在,我们已准备好通过 aspnet_regsql.exe
工具安装应用程序服务。
安装应用程序服务
若要启动 aspnet_regsql.exe
工具,请转到“开始”菜单,然后选择“运行”。 在文本框中输入 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe
,然后单击“确定”。 或者,可以使用 Windows 资源管理器向下钻取到相应的文件夹,然后双击 aspnet_regsql.exe
文件。 这两种方法都会得出相同的结果。
在没有任何命令行参数的情况下运行 aspnet_regsql.exe
工具将启动 ASP.NET SQL Server 安装向导图形用户界面。 通过向导,可以轻松地在指定的数据库上添加或删除 ASP.NET 应用程序服务。 向导的第一个屏幕(如图 7 所示)描述了该工具的用途。
图 7:使用 ASP.NET SQL Server 设置向导可添加成员身份架构(单击可查看全尺寸图像)
向导中的第二步询问我们是要添加应用程序服务还是删除它们。 由于我们想要添加 SqlMembershipProvider
所需的表、视图和存储过程,因此请选择“为应用程序服务配置 SQL Server”选项。 稍后,如果要从数据库中删除此架构,请重新运行此向导,但改为从现有数据库选项中选择“删除应用程序服务信息”。
图 8:选择“为应用程序服务配置 SQL Server”选项(单击以查看全尺寸图像)
第三步会提示输入数据库信息:服务器名称、身份验证信息和数据库名称。 如果一直关注本教程,并将 SecurityTutorials.mdf
数据库添加到 App_Data
,将其附加到 localhost\InstanceName
,并将其重命名为 SecurityTutorialsDatabase
,请使用以下值:
- 服务器:
localhost\InstanceName
- Windows 身份验证
- 数据库:
SecurityTutorialsDatabase
图 9:输入数据库信息(单击以查看全尺寸图像)
输入数据库信息后,单击“下一步”。 最后一步总结了将执行的步骤。 单击“下一步”安装应用程序服务,然后单击“完成”以完成向导。
注意
如果使用 Management Studio 附加数据库并重命名数据库文件,请确保在重新打开 Visual Studio 之前分离数据库并关闭 Management Studio。 若要分离 SecurityTutorialsDatabase
数据库,请右键单击数据库名称,然后从“任务”菜单中选择“分离”。
向导完成后,返回到 Visual Studio 并导航到数据库资源管理器。 展开 “表” 文件夹。 应会看到一系列表,其名称以前缀 aspnet_
开头。 同样,可以在“视图”和“存储过程”文件夹下找到各种视图和存储过程。 这些数据库对象构成了应用程序服务架构。 我们将在步骤 3 中检查成员身份和特定于角色的数据库对象。
图 10:已将各种表、视图和存储过程添加到数据库(单击以查看全尺寸图像)
注意
aspnet_regsql.exe
工具的图形用户界面安装整个应用程序服务架构。 但是,从命令行执行 aspnet_regsql.exe
时,可以指定要安装的特定应用程序服务组件(或删除)。 因此,如果要仅添加 SqlMembershipProvider
和 SqlRoleProvider
提供程序所需的表、视图和存储过程,请从命令行运行 aspnet_regsql.exe
。 或者,可以手动运行由 aspnet_regsql.exe
使用的 T-SQL 创建脚本的相应子集。 这些脚本位于 WINDIR%\Microsoft.Net\Framework\v2.0.50727\
文件夹中,名称如下:InstallCommon.sql
、InstallMembership.sql
、InstallRoles.sql
、InstallProfile.sql
、InstallSqlState.sql
等。
此时,我们创建了 SqlMembershipProvider
所需的数据库对象。 但是,我们仍需要指示成员资格框架应当使用 SqlMembershipProvider
(而不是 ActiveDirectoryMembershipProvider
),并且指示 SqlMembershipProvider
应该使用 SecurityTutorials
数据库。 我们将了解如何指定要使用的提供程序,以及如何在步骤 4 中自定义所选提供程序的设置。 但首先,让我们更深入地了解刚刚创建的数据库对象。
步骤 3:查看架构的核心表
在 ASP.NET 应用程序中使用成员资格和角色框架时,实现详细信息由提供程序封装。 在将来的教程中,我们将通过 .NET Framework 的 Membership
和 Roles
类来与这些框架进行交互。 使用这些高级 API 时,我们不需要关注底层的详细信息,例如执行了哪些查询或哪些表被 SqlMembershipProvider
和 SqlRoleProvider
所修改。
鉴于此情况,我们可以自信地使用成员资格和角色框架,而无需浏览步骤 2 中创建的数据库架构。 但是,创建表来存储应用程序数据时,可能需要创建与用户或角色相关的实体。 在应用程序数据表与步骤 2 中创建的表之间建立外键约束时,它有助于熟悉 SqlMembershipProvider
和 SqlRoleProvider
架构。 此外,在某些罕见情况下,我们可能需要直接在数据库级别与用户和角色存储系统进行交互,而不是通过 Membership
或 Roles
类。
将用户存储区分区到各个应用程序中
成员资格和角色框架的设计使单个用户和角色存储可以在许多不同的应用程序之间共享。 使用成员资格或角色框架的 ASP.NET 应用程序必须指定要使用的应用程序分区。 简言之,多个 Web 应用程序可以使用同一用户和角色存储。 图 11 展示了用户和角色存储被划分为三个应用程序:HRSite、CustomerSite 和 SalesSite。 这三个 Web 应用程序各自具有自己的唯一用户和角色,但它们都以物理方式将用户帐户和角色信息存储在相同的数据库表中。
图 11:用户帐户可能跨多个应用程序进行分区(单击以查看全尺寸图像)
aspnet_Applications
表定义这些分区。 使用此数据库存储用户帐户信息的每个应用程序都由此表中的一行表示。 aspnet_Applications
表有四列:ApplicationId
、ApplicationName
、LoweredApplicationName
和 Description
。ApplicationId
的类型为 uniqueidentifier
,是表的主键;ApplicationName
为每个应用程序提供唯一的人性化名称。
其他成员身份和角色相关表将重新链接到 aspnet_Applications
中的 ApplicationId
字段。 例如,包含每个用户帐户记录的 aspnet_Users
表具有 ApplicationId
外键字段。aspnet_Roles
表也是如此。 这些表中的 ApplicationId
字段指定用户帐户或角色所属的应用程序分区。
存储用户帐户信息
用户帐户信息存储在两个表中:aspnet_Users
和 aspnet_Membership
。 aspnet_Users
表包含保存基本用户帐户信息的字段。 三个最相关的列是:
UserId
UserName
ApplicationId
UserId
是主键(类型为 uniqueidentifier
)。 UserName
的类型为 nvarchar(256)
,并与密码一起构成用户凭证。 (用户的密码存储在 aspnet_Membership
表中。ApplicationId
将用户帐户链接到 aspnet_Applications
中的特定应用程序。 在 UserName
列和 ApplicationId
列上有一个复合 UNIQUE
约束。 这可确保在给定应用程序中,每个 UserName 都是唯一的,但它允许在不同的应用程序中使用相同的 UserName
。
aspnet_Membership
表包括其他用户帐户信息,例如用户的密码、电子邮件地址、上次登录日期和时间等。 aspnet_Users
和 aspnet_Membership
表中的记录之间存在一对一对应关系。 aspnet_Membership
中的 UserId
字段可确保此关系,该字段充当表的主键。 与 aspnet_Users
表一样,aspnet_Membership
包括一个 ApplicationId
字段,该字段将此信息绑定到特定的应用程序分区。
保护密码
密码信息存储在 aspnet_Membership
表中。 SqlMembershipProvider
允许使用以下三种方法之一将密码存储在数据库中:
- 清除 - 密码以纯文本形式存储在数据库中。 我强烈建议不要使用此选项。 如果数据库遭到入侵(可能是黑客找到了后门,也可能是心怀不满的员工拥有数据库访问权限),每个用户的凭据都有被盗的风险。
- 哈希 - 使用单向哈希算法和随机生成的盐值对密码进行哈希处理。 此哈希值(以及盐)存储在数据库中。
- 加密 - 密码的加密版本存储在数据库中。
使用的密码存储技术取决于 Web.config
中指定的 SqlMembershipProvider
设置。 我们将了解如何在步骤 4 中自定义 SqlMembershipProvider
设置。 默认行为是存储密码的哈希。
负责存储密码的列是 Password
、PasswordFormat
和 PasswordSalt
。 PasswordFormat
是一种 int
类型的字段,其值指示用于存储密码的技术:0 表示明文存储;1 表示散列存储;2 表示加密存储。 无论使用的密码存储技术如何,PasswordSalt
都会分配随机生成的字符串;仅当计算密码哈希时,才使用 PasswordSalt
的值。 最后,Password
列包含实际密码数据,可以是纯文本密码、密码哈希或加密密码。
表 1 说明了在存储密码 MySecret! 时,这三个列对于不同的存储技术可能是什么样子。 .
存储技术<_o3a_p /> | 密码<_o3a_p/> | PasswordFormat<_o3a_p /> | PasswordSalt<_o3a_p /> |
---|---|---|---|
清除 | MySecret! | 0 | tTnkPlesqissc2y2SMEygA== |
哈希 | 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= | 1 | wFgjUfhdUFOCKQiI61vtiQ== |
加密 | 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp | 2 | LSRzhGS/aa/oqAXGLHJNBw== |
表 1:存储密码 MySecret 时 Password-Related 字段的示例值!
备注
SqlMembershipProvider
使用的特定加密或哈希算法由 <machineKey>
元素中的设置确定。
存储角色和角色关联
角色框架允许开发人员定义一组角色,并指定哪些用户属于哪些角色。 此信息通过两个表在数据库中捕获:aspnet_Roles
和 aspnet_UsersInRoles
。 aspnet_Roles
表中的每个记录都表示特定应用程序的角色。 与 aspnet_Users
表非常类似,aspnet_Roles
表有三个与讨论相关的列:
RoleId
RoleName
ApplicationId
RoleId
是主键(类型为 uniqueidentifier
)。 RoleName
的类型为 nvarchar(256)
。 ApplicationId
将用户帐户链接到 aspnet_Applications
中的特定应用程序。 对 RoleName
和 ApplicationId
列有一个复合 UNIQUE
约束,从而确保在特定的应用程序中,每个角色名称都是唯一的。
aspnet_UsersInRoles
表充当用户和角色之间的映射。 只有两列——UserId
和 RoleId
——共同构成复合主键。
步骤 4:指定提供程序并自定义其设置
支持提供者模型的所有框架(如成员资格和角色框架)自身都缺乏实现细节,而是将实现责任委托给提供者类。 对于成员身份框架,Membership
类定义用于管理用户帐户的 API,但它不直接与任何用户存储进行交互。 相反,Membership
类的方法将请求移交给配置的提供程序 - 我们将使用 SqlMembershipProvider
。 当我们在 Membership
类中调用一个方法时,成员身份框架是如何知道将调用委托给 SqlMembershipProvider
的?
Membership
类具有一个 Providers
属性,该属性包含对所有已注册且可供成员身份框架使用的提供程序类的引用。 每个已注册的提供程序都有一个关联的名称和类型。 该名称提供一种用户友好的方法来引用 Providers
集合中的特定提供程序,而该类型标识提供程序类。 此外,每个已注册的提供程序可能包含配置设置。 成员资格框架的配置设置包括 PasswordFormat
和 requiresUniqueEmail
等。 有关 SqlMembershipProvider
使用的配置设置的完整列表,请参阅表 2。
Providers
属性的内容是通过 Web 应用程序的配置设置指定的。 默认情况下,所有 Web 应用程序都有一个名为 AspNetSqlMembershipProvider
、类型为 SqlMembershipProvider
的提供程序。 此默认成员身份提供程序已在 machine.config
中注册(位于 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG
):
警告
你要查找的示例似乎已移动! 放心,我们正在努力解决此问题。
如上述标记所示,<membership>
元素 定义成员资格框架的配置设置,而 <providers>
子元素 指定已注册的提供程序。 可以使用 <add>
或 <remove>
元素添加或删除提供程序;使用 <clear>
元素删除所有当前注册的提供程序。 如上述标记所示,machine.config
会添加一个名称为 AspNetSqlMembershipProvider
且类型为 SqlMembershipProvider
的提供程序。
除了 name
和 type
属性,<add>
元素还包含用于定义各种配置设置的值的属性。 表 2 列出了可用的 SqlMembershipProvider
特定配置设置,以及每个设置的说明。
注意
表 2 中指出的任何默认值都指在 SqlMembershipProvider
类中定义的默认值。 请注意,AspNetSqlMembershipProvider
中并非所有配置设置都对应于 SqlMembershipProvider
类的默认值。 例如,如果未在成员身份提供程序中指定,则 requiresUniqueEmail
设置默认为 true。 但是,AspNetSqlMembershipProvider
通过显式地将值指定为 false
来覆盖此默认值。
设置<_o3a_p /> | 描述<_o3a_p /> |
---|---|
ApplicationName |
回想一下,成员身份框架允许跨多个应用程序对单个用户存储进行分区。 此设置指示成员资格提供程序使用的应用程序分区的名称。 如果未显式指定此值,则会在运行时将其设置为应用程序的虚拟根路径的值。 |
commandTimeout |
指定 SQL 命令超时值(以秒为单位)。 默认值为 30。 |
connectionStringName |
要用于连接到用户存储区数据库的 <connectionStrings> 元素中的连接字符串的名称。 此值是必需的。 |
description |
提供已注册提供程序的用户友好描述。 |
enablePasswordRetrieval |
指定用户是否可以检索其忘记的密码。 默认值为 false 。 |
enablePasswordReset |
指示是否允许用户重置其密码。 默认为 true 。 |
maxInvalidPasswordAttempts |
在指定的 passwordAttemptWindow 期间,在锁定用户之前,给定用户可能出现的登录失败的最大次数。默认值为 5。 |
minRequiredNonalphanumericCharacters |
必须出现在用户密码中的最小非字母数字字符数。 此值必须介于 0 和 128 之间;默认值为 1。 |
minRequiredPasswordLength |
密码中所需的最小字符数。 此值必须介于 0 和 128 之间;默认值为 7。 |
name |
已注册供应商的名称。 此值是必需的。 |
passwordAttemptWindow |
跟踪失败登录尝试的分钟数。 如果用户在此指定的窗口中 maxInvalidPasswordAttempts 次提供无效的登录凭据,则会锁定这些凭据。默认值为 10。 |
PasswordFormat |
密码存储格式:Clear 、Hashed 或 Encrypted 。 默认值为 Hashed 。 |
passwordStrengthRegularExpression |
如果提供,则此正则表达式用于在创建新帐户或更改其密码时评估用户所选密码的强度。 默认值为空字符串。 |
requiresQuestionAndAnswer |
指定用户在检索或重置密码时是否必须回答其安全问题。 默认值为 true 。 |
requiresUniqueEmail |
指示给定应用程序分区中的所有用户帐户是否必须具有唯一的电子邮件地址。 默认值为 true 。 |
type |
指定提供程序的类型。 此值是必需的。 |
表 2:成员身份和 SqlMembershipProvider
配置设置
除了 AspNetSqlMembershipProvider
之外,其他成员身份提供程序都可以通过在 Web.config
文件中添加类似的标记来逐个应用程序进行注册。
注意
角色框架的工作方式大致相同:machine.config
中存在默认注册的角色提供程序,Web.config
中可以逐应用程序自定义已注册的提供程序。 我们将在将来的教程中详细介绍角色框架及其配置标记。
自定义SqlMembershipProvider
设置
默认 SqlMembershipProvider
(AspNetSqlMembershipProvider
)将其 connectionStringName
属性设置为 LocalSqlServer
。 如同 AspNetSqlMembershipProvider
提供程序一样,连接字符串名称 LocalSqlServer
定义在 machine.config
中。
警告
你要查找的示例似乎已经移到别处了! 放心,我们正在努力解决此问题。
可以看到,此连接字符串定义了一个 SQL 2005 Express Edition 数据库,位置为 |DataDirectory|aspnetdb.mdf。 字符串 |DataDirectory |在运行时转换为指向 ~/App_Data/
目录,因此数据库路径 |DataDirectory|aspnetdb.mdf转换为 ~/App_Data
/aspnet.mdf
。
如果未在应用程序的 Web.config
文件中指定任何会员提供程序信息,则应用程序将使用默认注册的会员提供程序 AspNetSqlMembershipProvider
。 如果 ~/App_Data/aspnet.mdf
数据库不存在,ASP.NET 运行时将自动创建它并添加应用程序服务架构。 但是,我们不想使用 aspnet.mdf
数据库;相反,我们希望使用我们在步骤 2 中创建的 SecurityTutorials.mdf
数据库。 可以通过以下两种方式之一完成此修改:
- 为
Web.config
中的连接字符串名称指定一个值LocalSqlServer
。 通过覆盖Web.config
中的LocalSqlServer
连接字符串名称值,我们可以使用默认注册的成员身份提供程序 (AspNetSqlMembershipProvider
),并使其正确地与SecurityTutorials.mdf
数据库一起工作。 如果你对AspNetSqlMembershipProvider
指定的配置设置感到满意,那么这种方法是可以的。 有关此方法的详细信息,请参阅 Scott Guthrie的博客文章,配置 ASP.NET 2.0 应用程序服务以使用 SQL Server 2000 或 SQL Server 2005。 - 添加
SqlMembershipProvider
类型的新注册提供程序,并将其connectionStringName
设置配置为指向SecurityTutorials.mdf
数据库。 此方法在除数据库连接字符串之外要自定义其他配置属性的方案中非常有用。 在我自己的项目中,我始终使用此方法,因为它的灵活性和可读性。
在我们添加引用 SecurityTutorials.mdf
数据库的新注册提供程序之前,需要先在 Web.config
的 <connectionStrings>
节中添加适当的连接字符串值。 以下标记添加了一个名为 SecurityTutorialsConnectionString
的新连接字符串,该连接字符串引用 App_Data
文件夹中的 SQL Server 2005 Express Edition SecurityTutorials.mdf
数据库。
警告
看起来你要查找的示例已经被移动了! 放心,我们正在努力解决此问题。
注意
如果使用备用数据库文件,请根据需要更新连接字符串。 有关形成正确的连接字符串的详细信息,请参阅 ConnectionStrings.com。
接下来,将以下成员资格配置标记添加到 Web.config
文件。 此标记会注册名为 SecurityTutorialsSqlMembershipProvider
的新提供程序。
警告
你要查找的示例似乎已移动! 放心,我们正在努力解决此问题。
除了注册 SecurityTutorialsSqlMembershipProvider
提供程序之外,上述标记还将 SecurityTutorialsSqlMembershipProvider
定义为默认提供程序(通过 <membership>
元素中的 defaultProvider
属性)。 请记住,成员身份框架可以有多个已注册提供程序。 由于 AspNetSqlMembershipProvider
注册为 machine.config
中的第一个提供程序,因此它充当默认提供程序,除非我们另有说明。
目前,应用程序有两个已注册提供程序:AspNetSqlMembershipProvider
和 SecurityTutorialsSqlMembershipProvider
。 但是,在注册 SecurityTutorialsSqlMembershipProvider
提供程序之前,我们可以通过在 <add>
元素之前立即添加 <clear />
元素 来清除以前注册的所有提供程序。 这将从已注册的提供程序列表中清除 AspNetSqlMembershipProvider
,这意味着 SecurityTutorialsSqlMembershipProvider
将是唯一已注册的成员身份提供程序。 如果使用此方法,则无需将 SecurityTutorialsSqlMembershipProvider
标记为默认提供程序,因为它是唯一注册的成员身份提供程序。 有关使用 <clear />
的详细信息,请参阅添加提供程序时使用 <clear />
。
请注意,SecurityTutorialsSqlMembershipProvider
的 connectionStringName
设置会引用刚添加的 SecurityTutorialsConnectionString
连接字符串名称,并且其 applicationName
设置已被设置为 SecurityTutorials 值。 此外,requiresUniqueEmail
设置已设置为 true
。 所有其他配置选项都与 AspNetSqlMembershipProvider
中的值相同。 如果愿意,可以随意在此处进行任何配置修改。 例如,可以通过要求两个非字母数字字符而不是一个字符,或者将密码长度增加到八个字符而不是七个字符来收紧密码强度。
注意
请注意,成员资格框架允许单个用户存储库可以在多个应用程序中进行分区。 成员身份提供程序的 applicationName
设置指示该提供程序在处理用户存储区时使用的应用程序。 请务必显式设置 applicationName
配置设置的值,因为如果未显式设置 applicationName
,则会在运行时将其分配给 Web 应用程序的虚拟根路径。 在应用程序的虚拟根路径不改变的情况下,这样的设置是有效的,但如果将应用程序移动到其他路径,则 applicationName
设置也会随之更改。 发生这种情况时,成员身份提供程序将开始使用与以前使用的应用程序分区不同的分区。 在移动之前创建的用户帐户将驻留在不同的应用程序分区中,并且这些用户将无法再登录到站点。 若需有关此事宜的更深入讨论,请参阅在配置 ASP.NET 2.0 成员身份和其他提供程序时始终设置 applicationName
属性。
总结
此时,我们已有一个配置了应用程序服务(SecurityTutorials.mdf
)的数据库,并已配置我们的 Web 应用程序,以便成员资格框架使用我们刚刚注册的 SecurityTutorialsSqlMembershipProvider
提供程序。 此已注册提供程序的类型是 SqlMembershipProvider
,并且已将其 connectionStringName
设置为适当的连接字符串 (SecurityTutorialsConnectionString
),并显式设置了其 applicationName
值。
现在,我们已准备好从应用程序使用成员资格框架。 在下一教程中,我们将了解如何创建新用户帐户。 接下来,我们将探索对用户进行身份验证、执行基于用户的授权,并将其他用户相关信息存储在数据库中。
快乐编程!
延伸阅读
有关本教程中讨论的主题的详细信息,请参阅以下资源:
- 在配置 ASP.NET 2.0 成员身份和其他提供程序时始终设置
applicationName
属性 - 配置 ASP.NET 2.0 应用程序服务以使用 SQL Server 2000 或 SQL Server 2005
- 下载 SQL Server Management Studio
- 检查 ASP.NET 2.0 的成员身份、角色和配置文件
- 成员身份提供程序的
<add>
元素 -
<membership>
元素 - 成员身份的
<providers>
元素 - 添加提供程序时使用
<clear />
- 直接使用
SqlMembershipProvider
本教程所含主题的视频培训
关于作者
斯科特·米切尔是多个 ASP/ASP.NET 书籍的作者,4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 Sams 在 24 小时内自学完 ASP.NET 2.0。 Scott 可以在 mitchell@4guysfromrolla.com 或通过他在 http://ScottOnWriting.NET 的博客联系到。
特别鸣谢
本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是 Alicja Maziarz。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请通过 mitchell@4GuysFromRolla.com联系我。