Sean "Early" Campbell
Scott "Adopter" Swigart
3 Leaf Solutions
2003 年 10 月
适用于:
Microsoft ASP.NET Whidbey
摘要:了解如何使用 ASP.NET Whidbey 中的成员 API 以及相关的安全控件轻松地对 Web 站点用户进行身份验证。在许多情况下,使用少量代码或无需使用代码就能添加强身份验证机制。(13 页打印页)
| 简介 | |
| 设置成员 | |
| ASP.NET Whidbey 中的安全控件 | |
| 成员身份 API | |
| 数据存储详细信息 | |
| 小结 |
注 本文写于该产品的发布和制造之前,因此,我们不能保证这里涉及的任何细节都与最终产品完全一致。文中信息描述的是本文发布之时的产品,仅供规划之用。这些信息可在任何时候更改,恕不预先通知。
Microsoft ASP.NET v1.0/1.1 为身份验证提供了可靠的、相对易于使用的 API。开发人员可以使用 Microsoft Windows、Microsoft Passport 或 Microsoft Forms 身份验证来确保他们站点的安全。但是,ASP.NET v1.0/1.1 中的身份验证模型有一个缺点,那就是 Web 开发人员必须开发他们自己的所有身份验证逻辑,并需要设计和提供用于存放那些凭据的数据存储。
即将推出的新版 ASP.NET 的代号为 ASP.NET "Whidbey"(与即将推出的 Microsoft Visual Studio .NET 版本代号一致),它所包含的成员功能大大减少了您在对站点的访问者进行身份验证时需要编写的代码量。首先,它减少了您管理用户名及密码信息的物理存储的需要。此外,它还为您的站点提供了用于管理成员的 UI 以及一组安全控件,这些控件支持身份验证、密码恢复、登录状态等。 像许多与 ASP.NET 应用程序相关的配置详细信息一样,与站点的成员设置有关的信息也存储在 web.config 文件中。但是,您不需要手动输入配置设置,因为它为您提供了向导,该向导使您能够很容易地为站点配置成员。完成该向导后,所有适当的配置项会写到 web.config 文件中。
作为第一步,我们将演练一个为 ASP.NET Whidbey 站点设置成员的简单示例。让我们看一下 ASP.NET Whidbey 中新的 Web 应用程序管理工具。
您可通过在 Microsoft Visual Studio .NET 2004 内定位到 WebSite | ASP.NET Configuration 菜单项,来访问该 Web 应用程序管理工具。

图 1. Web 应用程序管理工具
向导出现后,您需要单击页面顶部导航栏上的 Security 图标。
之后,出现的安全设置向导会为您提供两个选项。第一个选项应该在您首次为您的 ASP.NET 站点设置安全时使用。第二个选项使您可以修改您先前为站点配置的一组成员选项。

图 2. 安全设置选项
然后,在跳过安全设置向导的欢迎屏幕后,将出现如下屏幕,要求您指定访问方法。

图 3.指定访问方法
您在这里指定用户是从 Internet 还是仅从您的本地 Intranet 访问站点。此处,您的选择将影响是否将站点设置为使用 Windows 身份验证和域登录,或者用户在进入站点时是否必须输入唯一的电子邮件和密码的组合。在本例中,我们将选择“From a local area network”作为我们的访问方法。
如果您想创建新数据库以跟踪站点的用户信息,则可在下一个屏幕中单击一个复选框。然后,您需要指定用来存储成员信息的数据库的类型细节。您可以选择在 Microsoft Access 或 Microsoft SQL Server? 数据库中存储信息。此演练选择了 Access 数据库。
如果您选择创建新数据库,则会提示您指定数据库的名称和它的物理位置(对于 Access 数据库)或连接字符串信息(对于 SQL Server 数据库)。
下一步询问您是否要启用某些安全设置。正如您所看到的一样,您无需编写代码,便可很容易地为站点添加相当高级的身份验证机制。您可以指定每个电子邮件必须唯一,用户能够检索他们的密码,密码以安全格式存储以及用户能够在忘记密码时进行密码检索。您还可以设置特定问题和相关答案,以便用户在检索密码时使用。正如您所看到的一样,这些涵盖了密码管理的许多典型方面。
下一步让您指定站点的角色。虽然该步骤不是强制的,但最好使用基于角色的身份认证,因为它使您考虑应该允许给定的组执行的操作,而不是考虑允许特定用户执行的操作。然后可以轻松地把用户放置在这些角色中,并根据角色成员为其授予访问站点某些区域的权限。
添加角色只是指定想要添加的角色名称,然后在向站点添加用户时指定他们属于哪个角色。在添加用户时,可以指定他们的用户 ID、电子邮件地址、密码以及用于请求/响应的问题和答案(如果他们请求您将密码发送给他们)。如果您有所需要,该向导的另一部分还允许您向站点添加用户以及指定起始密码、密码请求问题和相关角色。
您还可以选择为站点指定身份验证或访问规则。这样,您可以为指定角色或用户限制对站点某些部分的访问。使用先前在向导中创建的用户和角色,您可以使用站点的树视图指定哪些用户和/或角色可以访问哪些部分。
完成该向导后,可以转到安全管理页面并修改已添加的设置、创建新用户和角色以及删除用户和角色。

图 4.“安全管理”页面
现在,您已经了解了为站点配置成员的基本知识,接下来您将看到如何存储成员配置信息。
正如前面所述,该成员向导只是把配置信息写到站点的 web.config 文件中。该向导执行的另一个重要任务是为实际成员信息创建数据存储。在上面的示例中,在 Web 站点的 Data 目录中创建了一个名为 MembershipDB 的 Access 数据库。Web.Config 中的下列设置包含与该存储通讯所需要用到的信息:
<connectionStrings>
<add name="webAdminConnection631977427651394288"
connectionString="c:\inetpub\wwwroot\MemberWeb\DATA\myDB.mdb" />
</connectionStrings>
<membership defaultProvider="myDB">
<providers>
<add name="myDB"
type="System.Web.Security.AccessMembershipProvider,
System.Web, Version=1.1.3300.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="webAdminConnection631977427651394288"
applicationName="/MemberWeb" requiresUniqueE-mail="true"
enablePasswordRetrieval="true"
enablePasswordReset="true" requiresQuestionAndAnswer="true"
passwordFormat="Encrypted" />
</providers>
</membership>
该向导至少向 web.config 文件添加两个键元素。其中第一个是到用于存储站点成员信息的数据库的连接字符串。下一个是 Membership 元素。Membership 元素指定将用于访问和存储成员信息的默认提供程序。Membership 元素内创建有一个数据提供程序,它详述了用户在该向导中导航时选择的不同选项。这里也存储着支持用户密码检索、密码重置和强密码存储的选项。
您可能注意到的另一个新元素是 roleManager 元素。如果您选择向站点添加角色,就会添加该元素。
<roleManager enabled="true" defaultProvider="membershipDB">
<providers>
<add name="membershipDB"
type="System.Web.Security.AccessRoleProvider, System.Web,
Version=1.1.3300.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="webAdminConnection631981026947021264"
applicationName="/MemberShipWeb" />
</providers>
</roleManager>
角色管理 API 是 ASP.NET Whidbey 的另一个功能。本文将不深入研究该 ASP.NET Whidbey 版本中的角色管理。但值得提及的是,ASP.NET Whidbey 提供的角色管理服务使您只需少量代码(如果需要代码)就能通过成员服务非常容易地向站点添加授权功能,以便完善您已有的身份验证功能。
向 web.config 文件添加最后一个元素:
<authentication mode="Forms">
<forms>
<credentials />
</forms>
<passport />
</authentication>
先前在指定访问方法时选择了选项“From the Internet”。这个选择为该选择生成适当的 <authentication>和 <forms> 元素。
启用站点的成员后,您可以开始利用 ASP.NET Whidbey 提供的新的安全控件。下表详述了这些控件。
| 控件 | 说明 |
Login | 为站点提供完整的登录功能。不需要代码。 |
LoginView | 根据用户的当前登录状态显示不同的页面模板。 |
PasswordRecovery | 根据用户名提供查找功能,还可提供使用问题和答案确认用户身份的可选功能。 |
LoginStatus | 根据用户的当前登录状态切换登录显示或注销显示。 |
LoginName | 在页面上检索并显示用户登录名。 |
为了说明这些控件中的一些,向站点添加了 Login.aspx 页面。该页面上事先已添加有一些 Login 安全控件和几个超级链接控件。通过简单地把 Login 控件从工具箱的“安全”部分中拖动出来,并把两个超级链接控件从工具箱的“Web 控件”部分拖动出来,可以生成该页面。
<asp:login id="Login1" runat="server" font-names="Verdana"
font-size="10pt" borderwidth="1px" bordercolor="#999999"
borderstyle="Solid" backcolor="#FFFFCC" submitbuttontext="Sign In"
failuretext="Unsuccesful login attempt. Please try again."
instructiontext="Enter your User Name and Password below.">
<titletextstyle font-bold="True" forecolor="#FFFFFF"
backcolor="#333399">
</titletextstyle>
</asp:login>
<br />
<asp:hyperlink id="HyperLink1" runat="server"
navigateurl="ForgotPassword.aspx">Forgot Password?
</asp:hyperlink>
<p />
<asp:hyperlink id="HyperLink2" runat="server"
navigateurl="CreateUser.aspx">First Time User?
</asp:hyperlink>
Login 控件处理与基础成员数据存储进行的所有通讯,以验证用户的凭据。您还可以通过使用模板很容易地修改 Login 控件的外观。

图 5. WebForm 页面上的 Login 控件和两个超级链接
稍后将讨论超级链接“Forgot Password?”和“First Time User?”。首先,将向该页面上添加另一个安全控件 LoginName。
<form runat="server"> <asp:loginname id="Loginname1" runat="server" /> </form>
有关 LoginName 控件,无需过多讨论。它只是把当前登录的用户名输出到 Web 页面上。LoginName 控件使您能够无需使用代码,就可以很简单地把当前登录用户名放置在用户正在查看的 Web 页面上。
在我们的示例站点中,如果用户通过在 Login.aspx 页面上的 Login 控件中输入适当的凭据成功地进行了身份验证,那么他们会被定向到 Default.aspx 页面。在该页面上,他们的用户名被 LoginName 控件显示在页面的顶部。
您可以使用某些其他属性进一步自定义 LoginName 控件的外观。在这种情况下,formatstring 属性用于指定其他信息:
<form runat="server">
<asp:loginname formatstring="Welcome Back {0}" id="Loginname1"
visble=true runat="server" />
</form>

图 6. 已验证身份的用户视图,通过指定 formatstring 属性的值获得
当然,现在您也许正在考虑其他的方案。对用户的简单问候语(例如,图 6 中的问候语)和支持更多格式的内容之间存在差异,一个有助于弥补这种差异的控件是 LoginView 控件。LoginView 控件使您能够一个页面拥有两个不同的模板。您可以为匿名用户指定其中的一个模板化页面视图,而为已验证身份的用户指定另一个模板化视图。

图 7. 在设计视图中可以很容易地修改模板
在上面的屏幕捕获中,您可以看到,在设计视图中可以很容易地修改模板。您还可以很容易地在 ASPX 页面的正文中声明性地进行模板修改。
<form runat="server">
<asp:loginview id="LoginView1" runat="server">
<anonymoustemplate>
<p>You are not logged in.</p>
</anonymoustemplate>
<loggedintemplate>
<p>
Welcome to our site
<asp:loginname id="LoginName1" runat="server" />.</p>
<p>
<br />
<asp:label id="lblUserInfo"
runat="server"></asp:label>
<br />
</p>
</loggedintemplate>
</asp:loginview>
</form>
通过使用 LoginView 控件,您可以很容易地为不同用户生成相同页面的两个不同视图。上面的代码将对已验证身份的用户显示问候语,而对未验证身份的用户将显示一条消息,以声明他们没有登录。很明显,您可以生成两个完全不同的页面,其中的一个页面将已验证身份的用户定向到只有已验证身份的用户才能访问的信息,而另一个页面将匿名用户定向到诸如如何登录的信息,或其他可能允许站点匿名用户访问的信息。
用户经常忘记他们的密码,因此需要一个用以获取密码的安全机制。ASP.NET Whidbey 中的 PasswordRecovery 控件使该方案非常易于实现。在演练该向导时,设置了几个用于启用密码恢复的选择。完成这些步骤后,您可以很容易地将 PasswordRecovery 控件添加到站点的页面上。正如下面的代码示例显示的一样,PasswordRecovery 控件非常简单。
<form runat="server">
<asp:passwordrecovery id="Passwordrecovery1" runat="server" font-
names="Verdana" font-size="10pt" bordercolor="#999999"
borderwidth="1px" borderstyle="Solid" backcolor="#FFFFCC"
visible=true>
<titletextstyle font-bold="True" forecolor="#FFFFFF"
backcolor="#333399">
</titletextstyle>
</asp:passwordrecovery>
</form>
正如您从上面的代码中所看到的一样,设置的所有属性都很基本。这是在将密码以电子邮件方式发送给用户之前向他们提示问题以及输入相关答案时,该控件在 Web 页面上所呈现的外观。
为实现此功能,您还需要在 web.config 中手动添加一项,该项指向将把电子邮件传送给用户的 SMTP 中继服务器。
<smtpMail serverName="localhost"> </smtpMail>

图 8.“Forget Your Password?”对话框
用户在单击“提交”按钮后,将收到一封包含他们的密码信息的电子邮件。
您或许会想“这非常棒,但如果我想 编写代码该怎么办呢?是否有成员身份 API?”是的,有成员身份 API。而且它非常易于使用。我们的示例站点有一个附加页面,该页面为我们站点的新访问者提供创建新用户帐户的功能。在当前版本的 ASP.NET Whidbey 中,这是通过用代码调用成员身份 API 来实现的。
设想一个一目了然的 Web 窗体页面可接受用户输入的用户名、密码和电子邮件地址。在这些输入域的下面有一个按钮,该按钮允许用户使用输入的信息为站点创建新用户帐户。使用成员身份 API,只需一行代码便可创建用户并把他们的信息保留在所选的数据存储中。
Sub btnCreateUser_Click(ByVal sender As Object, ByVal e As
System.EventArgs)
Membership.CreateUser _
(txtUserName.Text, txtPassword.Text, txtE-mail.Text)
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, False)
End Sub
正如您在上面的代码中看到的一样,在 ASP.NET Whidbey 中创建新用户只是调用 Membership 类的 CreateUser 方法,并传递适当的参数。第二行只是对用户进行身份验证并将他们重定向回他们最初请求的页面,在本例中是站点的 Default.aspx 页面。
成员身份 API 还支持更新用户、删除用户以及收集有关当前登录用户的信息的功能。下表详述了 Membership 对象的一些更有趣的方法。
| 方法 | 说明 |
CreateUser | 用于创建新的用户帐户。返回一个带有与用户有关的信息的 MembershipUser 对象。 |
DeleteUser | 删除指定的用户帐户。 |
FindUsersByName | 查找匹配用户名任何部分的用户集合。 |
GeneratePassword | 允许生成随机密码。 |
GetAllUsers | 返回成员身份数据库中的所有用户。 |
GetNumberOfUsersOnline | 返回当前的联机用户数量。 |
GetUser | 返回特定用户帐户的 MembershipUser 对象。 |
GetUserNameByE-mail | 返回使用特定电子邮件地址的用户的 MembershipUser 对象。 |
UpdateUser | 使您能够更新特定用户帐户的密码或其他信息。 |
ValidateUser | 验证给定用户帐户的用户名和密码的组合。 |
正如先前讨论的一样,用户名、密码、电子邮件等方面的成员身份信息可以存储在 Access 或 SQL Server 数据库中。这两种数据库都有预定义架构。在 Access 数据库中,只是把模板数据库复制到站点中的 Data 文件夹中。该模板数据库是从系统根目录下的 Microsoft .NET 框架安装目录中复制的。在 SQL Server 数据库中,将运行一个脚本来创建一个具有指定名称的数据库。
ASP.NET Whidbey 提供了丰富的新功能,以便为访问 Web 站点的用户提供成员身份支持。您可以使用向导创建基本配置,但该信息完全存储在 web.config 文件中,如果您愿意,可以在此文件中直接修改信息。成员身份服务同时还创建存储用户信息所需要的初始数据库基础结构。如果您相信 ASP.NET Whidbey 的能力,许多方案只需少量代码或无需代码就能得到解决。尽管如此,仍然公开了丰富的 API,以便您完全控制您的解决方案。