16.4 基于表单的身份验证
知识点讲解:光盘:视频\PPT讲解(知识点)\第16章\基于表单的身份验证.mp4
在网站应用中,使用最多的验证方式是表单,无论是会员登录还是用户注册,都是通过表单实现的。作为一个Web网站,登录表单既直观又简捷,ASP.NET也支持基于表单的验证方式。如果需要为网站创建一套自定义的用户注册系统,那么基于表单的身份验证(以下简称表单验证)是非常合适的。因此,可以使用任何的载体(如配置文件或者数据库)来存储用户名和密码。表单验证通过Cookie判断用户票据,如果一个没有通过身份验证的用户请求一个页面,那么他会被自动转到登录页面,用户登录后又会转到原来的请求页面。
表单验证不负责提供完整的登录验证、用户注册等操作,它仅仅对用户进行身份验证,将未经身份验证的用户重定向到登录页面,并执行所有必要的 Cookie 管理。表单身份验证的基本处理流程如图16-16所示。
图16-16 表单身份验证处理流程
1.启用表单身份验证
启用表单验证的操作步骤如下。
(1)配置根目录Web.config文件的<authentication>节点,以启用表单验证。
(2)配置必要目录Web.config文件的<authorization>节点,为指定目录关闭匿名访问权限。
(3)创建一个登录页面,允许用户输入用户名和密码。
例如下面的配置代码。
<configuration>
<system.web>
<authentication mode="Forms"/>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
2.配置表单身份验证
在配置文件Web.config中,<authentication>节点存在一个可选的<forms>元素,其设置格式如下。
<authentication mode="Forms">
<forms
name=".ASPXAUTH"
loginUrl="login.aspx"
defaultUrl="default.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
slidingExpiration="true"
enableCrossAppRedirects="false"
cookieless="UseDeviceProfile"
domain="">
</forms>
</authentication>
上述格式中各个属性的具体说明如表16-1所示。
表16-1 <forms>元素属性信息
属 性 |
说 明 |
---|---|
name |
指定要用于身份验证的HTTP Cookie。如果正在一台服务器上运行多个应用程序,并且每个应用程序都需要唯一的Cookie,则必须在每个应用程序的Web.config文件中配置Cookie名称。默认值为.ASPXAUTH |
loginUrl |
指定如果找不到任何有效的身份验证Cookie,将请求重定向到用于登录的URL。默认值为login.aspx |
defaultUrl |
定义在身份验证之后用于重定向的默认URL。默认值为default.aspx |
protection |
指定Cookie使用的加密类型(如果有)。此属性可以为下列值之一
|
timeout |
指定Cookie过期前逝去的时间(以整数分钟为单位)。如果SlidingExpiration属性为True,则timeout属性是滑动值,会在接收到上一个请求之后的指定时间(以分钟为单位)后过期。为防止危及性能并避免向开启Cookie警告的用户发出多个浏览器警告,当指定的时间逝去大半时将更新 Cookie。这可能导致精确性受损。持久性Cookie不超时。默认值为30(分钟) |
path |
为应用程序发出的Cookie指定路径默认值是斜杠(/),这是因为大多数浏览器是区分大小写的,如果路径大小写不匹配,浏览器不会送回Cookie |
requireSSL |
指定是否需要SSL连接来传输身份验证 Cookie。此属性可以为下列值之一
|
SlidingExpiration |
指定是否启用弹性过期时间。可调过期将Cookie的当前身份验证时间重置为在单个会话期间收到每个请求时过期。此属性可以为下列值之一
|
enableCrossApp-Redirects |
表明是否将通过身份验证的用户重定向到其他 Web 应用程序中的URL。此属性可以为下列值之一
|
cookieless |
定义是否使用Cookie以及Cookie的行为。此属性可以为下列值之一
|
domain |
指定在传出Forms身份验证Cookie中设置的可选域。此设置的优先级高于<httpCookies>元素中使用的域。默认值为空字符串("") |
3.配置表单授权
在介绍基于Windows的身份认证的时候,已经简单介绍了配置授权用户和角色的方法。其实,ASP.NET用于控制对URL资源的客户端访问。它对于用于生成请求的HTTP方法(GET或POST)是可配置的,并且可配置为允许或拒绝访问用户组或角色组。例如在下面的配置代码中,向名为“someone”的用户和名为“Admins”的角色授予访问权,而所有其他用户的访问被拒绝。
<authorization>
<allow users="someone" />
<allow roles="Admins" />
<deny users="*" />
</authorization>
允许的授权指令元素为allow或deny,每个allow或deny元素都必须包含users或roles属性。通过提供一个逗号分配的列表,可在单个元素中指定多个用户或角色。
例如,在网站目录下创建一个“Down”文件夹,在该文件夹下放置一个123.rar文件,然后在该文件夹下再创建一个Web.config文件,用于配置授权。
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
上述配置限制了匿名用户对这个文件夹中资源的访问。但是要让ASP.NET引擎“接管”对资源的授权,还需要为某个扩展名的文件添加ASP.NET映射,即对网站的虚拟目录添加rar文件到ASP.NET引擎的映射,如图16-17所示。
图16-17 添加扩展名映射
现在,输入“http://xxxx/Down/123.rar”来尝试下载文件,ASP.NET会自动转到登录页面要求登录。
4.登录与注销
在使用表单登录时,需要通知表单验证用户已经登录,要求表单验证写入用户凭据,并通知表单验证删除用户凭据。要实现上述功能需求,可以按照如下操作步骤进行操作。
(1)配置Web.config文件,启用表单验证,并且设置登录页面和默认首页的地址。
<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms
name=".ASPXAUTH"
loginUrl="MyLogin.aspx"
defaultUrl="Download/Download.aspx">
</forms>
</authentication>
</system.web>
</configuration>
(2)创建一个MyLogin.aspx页面,在该页面上放置一个按钮控件和一个多选框控件。
<asp:CheckBox ID="cb_RememberMe" runat="server" Text="记住我?" />
<asp:Button ID="btn_Login" runat="server" Text="登录" />
双击【登录】按钮,单击事件处理方法如下。
protected void btn_Login_Click(object sender, EventArgs e)
{
FormsAuthentication.RedirectFromLoginPage("test", cb_RememberMe.Checked);
}
登录操作仅仅只需要一行代码。在这里,我们“通知”表单验证,名为“test“的用户已经通过身份验证,可以写入票据了。第二个bool型的参数指示是否要持久保留票据(以后用户访问这个页面不需要再次登录)。
为了简单,在此没有根据用户名和密码来判断用户是否是合法用户,此处的RedirectFrom- LoginPage()方法仅仅是保存用户票据并把用户重定向到来源页面。
(3)在前面介绍的Down目录中创建一个Download.aspx页面,并在此页面上添加一个链接,用于下载文件;添加一个按钮,用于退出操作。
<a href="11.rar">下载</a><br />
<asp:Button ID="btn_Logout" runat="server" Text="注销" />
【注销】按钮的单击事件处理方法如下。
protected void btn_Logout_Click(object sender, EventArgs e)
{
// 删除用户票据
FormsAuthentication.SignOut();
// 重定向到登录页面
FormsAuthentication.RedirectToLoginPage();
}
表单验证“接管”了票据的写入和删除,而没有对Cookie进行任何编码就实现了用户身份票据在Cookie中的保存和删除。
(4)开始测试,具体过程如下。
第1步:打开MyLogin.aspx进行登录,登录后页面直接转到默认的首页Down目录下的Download.aspx(根据defaultUrl属性的设置)。
第2步:直接打开通过身份验证用户才能访问的Down/Download.aspx,页面自动重定向到MyLogin.aspx(根据loginUrl属性的设置),要求用户登录,登录后还是自动返回到Download. aspx。由于在前一节中已经添加了对rar文件的扩展名映射,因此未验证用户直接访问123.rar文件后也会转到MyLogin.aspx。
第3步:测试持久票据。在登录的时候选中“记住我”复选框,单击登录后页面转到下载页面。关闭浏览器后直接访问下载页面,发现页面能正常打开,说明用户票据确实被持久保存了。单击【注销】按钮,页面又回到MyLogin.aspx。
5.Web.config进行身份验证
对于内部使用的小型系统,基本不需要对外开放注册等功能,而且用户的角色也相对单一,这时可以直接使用Web.config保存用户名和密码,并且使用表单验证来验证。例如,修改Web.config文件的<forms>部分。
<forms
name=".ASPXAUTH"
loginUrl="MyLogin.aspx"
defaultUrl="Down/Download.aspx">
<credentials passwordFormat="Clear">
<user name="test" password="test"/>
</credentials>
</forms>
在此可以用明文存储用户名和密码(都是“test”),然后修改MyLogin.aspx的【登录】按钮的单击事件处理方法。
protected void btn_Login_Click(object sender, EventArgs e)
{
if (FormsAuthentication.Authenticate("test", "test"))
FormsAuthentication.RedirectFromLoginPage("test", cb_RememberMe.Checked);
else
Response.Write("用户名或者密码错误");
}
通过Authenticate()方法就能直接对照配置文件中的凭据验证用户名和密码。如果觉得明文保存密码不合适,可以修改Web.config文件,选择“MD5”或者“SHA1”加密算法。读者可能会问,怎么知道一个密码加密后的密码是什么呢?可以使用HashPasswordForStoringIn ConfigFile()方法。此方法是一个经典的开源MD5加密算法实现,读者可以直接调用,修改MyLogin.aspx的Page_Load事件处理方法。
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(FormsAuthentication.HashPasswordForStoringInConfigFile
("test","SHA1"));
}
上述代码输出了“test”这个密码经过SHA1加密后的密码,然后把这个密码存入Web.config中即可。
<credentials passwordFormat=:SHA1">
<user name="test" password="A94A8FE5CCB19BA61C4C0873D391E987982FBBD3"/>
</credentials>
6.获取用户信息
获取经过表单身份验证后的用户信息和用户凭据信息十分重要,为此可以在Down目录下创建一个UserInfo.aspx,并对Page_Load事件处理方法进行如下修改。
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
FormsIdentity identity = User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = identity.Ticket;
Response.Write(string.Format("用户名:{0}<br/>", identity.Name));
Response.Write(string.Format("创建时间:{0}<br/>", ticket.IssueDate));
Response.Write(string.Format("过期时间:{0}<br/>", ticket.Expiration));
Response.Write(string.Format("是否持久:{0}<br/>", ticket.IsPersistent));
}
else
FormsAuthentication.RedirectToLoginPage();
}
在这里,我们输出了通过身份验证的用户名,以及身份票据的创建时间、过期时间和持久性,在MyLogin.aspx页面登录后(选择“记住我”复选框),访问UserInfo.aspx页面的输出结果如图16-18所示。
图16-18 输出用户信息