基于FORM的验证
基于FORM的验证,实际上是允许应用程序定义自己的验证画面和可信性验证。当用户进入时,出现事先定义的画面并请求输入验证要素,输入完毕,用用户逻辑对输入验证,通过,则进入应用,否则,返回起始输入画面。基于FORM的验证,通常都采用cookies技术来实现验证任务。启用基于FORM的验证,是在config.web中设置<authentication mode=”Cookie” />来实现的。
例如:采用基于Form的验证方式,拒绝匿名用户进入的配置段如下:
<!--config.web->
…
<configuration>
<security>
<authentication mode="Cookie"/>
<authorization>
<deny users="?" />
</authorization>
</security>
</configuration>
…
其中,<authorization>一节中,用deny标识表示禁止某种用户,“?”代表匿名用户,“*”代表所有用户,当然在users后也可以跟指定的用户,表示只拒绝指定的用户。
此外,在配置节中还有一个cookie标识,它规定了Cookie的行为,也较为重要。Cookie标识有三个属性:
•decryptionkey 用于指定对cookie加解密的密钥。如果不指定或指定为autogenerate,密钥将采用Crypto API产生的系统密钥。当指定为autogenerate时,产生的密钥和机器相关,因而不能跨机器和平台,除非显示给出密钥。
•loginurl 验证页面。当用户验证失败以后,被定向到的页面,它可以是在本地,也可以是其他机器上。
•cookie 指定用于验证任务的cookie的名字。由于在同一台机器上,可能存在多个应用,而同一应用使用一个cookie名,所以同一机器上的cookie名字不能相同。
例如,在config.web中有如下定义:
<!--config.web -->
…
<security>
<authentication mode="Cookie">
<cookie decryptionkey="autogenerate" loginurl="login.aspx"
cookie=".ASPXCOOKIEDEMO" />
</authentication>
</security>
…
从这段配置,我们可以知道cookie的密钥由系统产生,当验证失败以后,页面将跳转至login.aspx,cook名为“.ASPXCOOKIEDEMO”
在基于FORM的验证中,一个常用到的对象是CookAuthentication。
CookAuthentication有4个比较重要的方法:
•RedirectFromLoginPage方法,它通常在验证成功以后,从用户的验证画面返回用户开始请求的页面。它带有两个参数,第一个为cookie要记录的用户名,第二个表明是否记录到永久性cookie中。
例如:
CookieAuthentication.RedirectFromLoginPage(“Chen”,True)
表示把用户“Chen”记录到硬盘上的cookie记录中,然后跳转到用户原先请求的页面上。
•GetAuthCookie 从cookie中取得指定用户名的值。它的参数和RedirectFromLoginPage方法是一样的。
例如:
CookieAuthentication.GetAuthCookie(“Chen”,Flase)
表示从当前连接的cookie中取出用户名为chen的值
•SetAuthCookie 把指定用户名存入cookie中。参数和GetAuthCookie方法一致
例如:
CookieAuthentication.SetAuthCookie(“Chen”,Flase)
表示把用户“Chen”记录到连接过程中存在的cookie中
•SignOut 删除当前用户的验证Cookie,它不会理会Cookie到底是在内存,还是在硬盘上。
下面我将介绍一个完整的例子:
application\delault.aspx文件:
<%@ Import Namespace="System.Web.Security " %>
<html>
<script language="VB" runat=server>
Sub Page_Load(Src As Object, E As EventArgs)
Welcome.Text = "Hello, " + User.Identity.Name
End Sub
Sub Signout_Click(Src As Object, E As EventArgs)
CookieAuthentication.SignOut()
‘删去Cookies
Response.Redirect("login.aspx")
‘返回验证画面
End Sub
</script>
<body>
<h3><font face="Verdana">使用Cookie验证方式</font></h3>
<form runat=server>
<h3><asp:label id="Welcome" runat=server/></h3>
<asp:button text="Signout" OnClick="Signout_Click" runat=server/>
</form>
</body>
</html>
application\login.aspx文件:
<%@ Import Namespace="System.Web.Security " %>
<html>
<script language="VB" runat=server>
Sub Login_Click(Src As Object, E As EventArgs)
If (UserEmail.Value = "test@263.net" Or UserEmail.Value = "try@163.net") And UserPass.Value = "password"
‘如果用户为test@263.net或者是try@163.net而且口令为password,就认为通过验证
CookieAuthentication.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked)
‘记录Cookie并且跳转到请求的页面
Else
Msg.Text = "非法用户或口令: 请重试"
End If
End Sub
</script>
<body>
<form runat=server>
<h3><font face="Verdana">登录窗口</font></h3>
<table>
<tr>
<td>Email地址:</td>
<td><input id="UserEmail" type="text" runat=server/></td>
<td><ASP:RequiredFieldValidator ControlToValidate="UserEmail" Display="Static" ErrorMessage="*" runat=server/></td>
</tr>
<tr>
<td>口令:</td>
<td><input id="UserPass" type=password runat=server/></td>
<td><ASP:RequiredFieldValidator ControlToValidate="UserPass" Display="Static" ErrorMessage="*" runat=server/></td>
</tr>
<tr>
<td>永久性Cookie:</td>
<td><ASP:CheckBox id=PersistCookie runat="server" /> </td>
<td></td>
</tr>
</table>
<asp:button text="Login" OnClick="Login_Click" runat=server/>
<p>
<asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat=server />
</form>
</body>
</html>
config.web文件:
<configuration>
<security>
<authentication mode="Cookie">
<!--采用cookie验证方式-->
<cookie decryptionkey = "autogenerate" loginurl = "login.aspx" cookie = ".ASPXUSERDEMO" />
<!--密钥系统产生,登录页面为login.aspx,记录的Cookie名为.aspuserdemo-->
</authentication>
<authorization>
<deny users="test@263.net" />
<!--虽然程序中有两个用户test@263和try@163.net可以进入,但此处封掉test@263.net,观察deny标识是否有效-->
<deny users="?" />
<!--拒绝匿名用户anonymous-->
</authorization>
</security>
<globalization requestencoding="UTF-8" responseencoding="UTF-8" />
</configuration>
我们还可以在config.web中设置用户和密码,当用户在验证窗口输入用户和密码后,将其带入CookieAuthenticationManager.Authenticate,有它来验证是否是合法用户。
在config.web中设置用户和密码使用credentials标识,它有一个属性passwordformat,决定口令存储的方式。Passwordformat可以为以下值:
•Clear 口令以纯文本方式存储。
•SHA1 口令以SHA1方式存储。
•MD5 口令以MD5方式存储。
例如: 在一个配置文件中,
<!--config.web-->
…
<configuration>
…
<security>
<authentication>
<credentials passwordformat=”SHA1” >
<user name=”Li” password=”GASDFSA9823598ASDBAD”/>
<user name=”Chen” password=”ZASDFADSFASD23483142”/>
</credentials>
</authentication>
</security>
…
</configuration>
从这个例子,我们看到credentials标识中的passwordformat为SHA1,所以下面的用户的密码是以SHA1方式加密以后的格式。在<credentials>和</credentials>之间我们定义了两个用户“Chen”和”Li”,其密码不可识别。
4.5.4 授权用户和角色
URL授权控制对资源的访问权限。它可以使一些用户和角色对资源有存取权限,也可以拒绝某些用户和角色对资源的存取。甚至它还可以决定能够存取资源的HTTP方法(例如:不允许get,允许POST等等)。
对于授权用户和角色的控制,asp.net通过配置文件config.web中的<authorization>标识段来实现。<allow>标识表示允许对资源的访问,<deny>标识表示拒绝对资源的访问。
它们都有两个属性,users和roles分别表示用户和角色。
我们来看一个实例:
<!--config.web->
…
<configuration>
<security>
<authorization>
<allow users="nobody@163.net" />
<allow roles="Admins" />
<deny users="*" />
</authorization>
</security>
</configuration>
…
它表明了这样一个事实,用户“nobody@163.net“和角色Admins有访问本站点的权力,其他用户对本站点的访问将被拒绝。也就是用户nobody@163.net和角色Admins分别是授权用户和授权角色。
同样,我们可以定义多个用户或者角色被授权或禁止,它们之间以“,“分隔。
例如:
…
<allow users=”Chen,Li,Wang” />
<deny roles=”Admins,Everyone” />
…
表示用户“Chen”、“Li”、”Wang”是授权用户,但是角色为“Admins”或者是”Everyone”的被排除在外。
它的效果和分开写是一样的,如上例也可以写为:
…
<allow users=”Chen” />
<allow users=”Li” />
<allow users=”Wang” />
<deny roles=”Admins” />
<deny roles=”Everyone” />
…
此外,还可以决定用户的某种HTTP方法是否可以被允许,方法是使用verb属性来表明对那种HTTP方法操作。
例如:
…
<allow verb=post users=”Chen,Li” />
<deny verb=get roles=”everyone” />
…
表示允许用户“Chen”,”Li“采用post方法访问资源,而拒绝角色everyone的get方式对资源的访问。
符号“*“和”?“在<allow>和<deny>标识中有特殊的含义。”*“表示任何用户,”?“表示匿名用户。
例如:
…
<authorization>
<allow users=”*” />
<deny users=”?” />
</authorization>
表示除了匿名用户以外的所有用户都被允许访问本站点。
由前面的学习我们知道,在asp.net中应用是树型分层的,所以其配置文件也是呈层次结构,这也就导致了用户和角色的授权不是单一的结果,它要取决于沿树型结构上所有配置文件指定的结果的合集,而且越接近叶节点的配置越是有效。
例如:访问http:www.my.com/MyApp/a.aspx
在http:www.my.com的根目录下的配置文件config.web有如下内容:
…
<security>
<authorization>
<allow users=”*” />
</authorization>
</security>
…
而在MyApp目录下有配置文件config.web内容如下:
…
<security>
<authorization>
<allow users=”Chen” />
<deny users=”*” />
</authorization>
<security>
…
那么,授权用户的集合到底是怎样的呢?asp.net首先取得站点根目录下的配置,即所有用户都被允许访问,然后asp.net进入Myapp的目录取得其下的配置,除用户“Chen”以外所有的用户被拒绝,最后合并两个授权集合,并且如果两者之间有冲突,以后者为准。所以最终的授权集合为用户“Chen”,其他用户被拒绝。