deargem / 我的图书馆 / 关于Forms验证 - 科比的日志 - 网易博客

分享

   

关于Forms验证 - 科比的日志 - 网易博客

2009-11-11  deargem

关于Forms验证

关于Forms验证的最好的教程,我觉得是microsoft press 出的黑皮书《microsoft.net 程序设计技术内幕》里的关于这一部分的讲解,此书的中文版由清华大学出版社出版。大家方便找到的话,可以看看。

窗体验证是asp.net最酷的新特性之一。简单说,窗体验证是一种安全机制,它通过要求用户在web窗体中输入凭据(通常是用户名和密码)来验证用户身份。您可以在web.config中指定登录页面并告诉asp.net登录页面保护什么资源。当用户第一次试图访问被保护资源时,asp.net会把用户重新定向到您的登录页面。如果登陆成功,asp.net会以cookie的形式发给用户一个验证票据,并把用户重定向到最初请求的页面。这张票据使得用户不必重复登录,就可以多次访问您站点上的被保护内容。您控制这张票据的生存期,所以由您决定登录适用于多长时间。

上面这段话明白吗?我们可以想以前asp的时候,要保护的页面都会有对cookie(或session)的判断,根据cookie的值来判断用户是否有访问这个页的权力。而具体做的时候,都是先要求用户登陆,成功后就把用户信息保存在cookie里面,然后用户就可以访问受保护的页。而现在asp.net提供了一种更加方便的功能来替你完成这些工作,就是上面说的Forms验证。就像分页,以前asp不也替你完成了嘛,可是到了asp.net这里,就得自己动手了……

过程是先建一个文件夹,然后把要保护的页面放进去,接着设置一下web,config,这样就完成了保护。如果你要访问这个文件夹,就会被强制转到预先设定的登录页面,你填上正确的用户名和密码,提交,系统验证后,就把你的登陆信息写到cookie里面,这样你再去访问那个文件夹,就可以进去了,因为你的登陆凭证已经保存到cookie里面了,系统检查后,知道你不是坏人,于是就……这个过程还是和以前asp时的过程差不多。

下面是具体的操作,先要建一个asp.net应用程序,这里面至少要有一个登录用的页面,然后修改你的根目录下的web.config,把验证那一块改成Forms验证模式。

[Copy to clipboard] [ - ]

CODE:

<authentication mode="Forms" >

<forms loginUrl="login.aspx">

</forms>

</authentication>

注意里面有一个forms节,定义了登录页面的位置,如果不指定,则默认是根目录下的login.aspx,还有,里面是区分大小写的。

通过这个设置,系统就知道这个asp.net应用程序使用Forms验证。

接下来在要保护的文件夹里放一个web.config,要注意的是,这个子文件夹里的web.config的实际内容不能像根目录下的那个一样多,否则就会出现“配置错误”,提示“在应用程序级别以外使用注册为 allowDefinition='MachineToApplication' 的节是错误的。导致该错误的原因可能是在 IIS 中没有将虚拟目录作为应用程序进行配置。”具体应该怎么做我也不清楚,总之这个web.config只要有下面的内容就ok了

[Copy to clipboard] [ - ]

CODE:

<configuration>

<system.web>

<authorization>

<deny users="?"></deny>

</authorization>

</system.web>

</configuration>

这是一个授权节,此节设置应用程序的授权策略。可以允许(allow)或拒绝(deny)不同的用户或角色访问应用程序资源。通配符: "*" 表示任何人,"?" 表示匿名(未经身份验证的)用户。看我们上面的设置知道,这样配置就是拒绝未经身份验证的用户访问。

然后可以试试访问那个受保护的文件夹里的页面了,嘿嘿,是不是立刻就被转到login.aspx了?这就是Forms验证的威力了,你必须要在这里正确登陆,然后才可以访问受保护的资源。

接下来自然就是登陆的问题了。

想想在asp的时代,我们的登陆事件是这样的:

[Copy to clipboard] [ - ]

CODE:

sql="select name,password from yourtable where name="&name&" password="&password

set rs=con.execute(sql)

if not rs.eof

cookie("login")="ok"

end if

上面是基本的过程了,注意这个做法是极不安全的,这里只是一个示例,而在Forms验证时的过程也差不多,即

if(1.输入的用户名和密码合法) then

2.给用户设定登陆凭证

end if

先看第一步,怎样检查输入的用户名和密码合法,这里有两个办法,如果你是把用户名和密码存在数据库里面,那就用以前的办法来解决,比如是islogin(string name,string password)方法,如果你输入正确的用户名和密码的话,这个方法就返回true。这个办法适用于很多用户的时候。 如果你的用户数量很少,那就可以考虑第二种办法,即把用户和密码放到web.config里。办法就是在根目录下的web.config文件中加入一个credentials节,这个是包含在forms节里面的

[Copy to clipboard] [ - ]

CODE:

<authentication mode="Forms" >

<forms loginUrl="login.aspx">

<credentials passwordFormat="Clear">

<user name="notus" password="wei"/>

</credentials>

</forms>

</authentication>

在这里设置后,程序中的判断是用System.Web.Security的FormsAuthentication类的一个方法System.Web.Security.FormsAuthentication.Authenticate(string name,string password),这个就是用来根据web.config文件中的credentials节指定的用户名和密码来进行合法性判断,如果你输入正确的话,这个方法就返回true。

验证完后,就进入第二个步骤给用户设定登陆凭证,这里也是用到System.Web.Security的FormsAuthentication类的一个方法

System.Web.Security.FormsAuthentication.RedirectFromLoginPage(string,bool)这个方法接受两个参数,第一个string是用语cookie身份验证的用户名称,一般就用用户名,第二个是bool值,用于指定此cookie是临时的,还是永久性的,如果这里用false,那就是临时性的。临时性的cookie的生存期可以在web.config的forms节中指定

<forms loginUrl="login.aspx" timeout="10">

这里是把超时时间设为10分钟。而永久性cookie的生存期是50年,并且设定后就不可以更改,一般如果选择永久性的cookie的话,可以通过编程的办法来改变这个值,毕竟50年实在是太长了。

这个方法除了设定用户登陆凭证外,在最后还会把用户重定向到最初请求的页面,即当你没有登录而直接进入受保护的文件夹时想去的那个页面。如一开始直接进入登录页面,则最后会转向根目录下的default.aspx。

下面是具体的代码演示,这段代码是单击登陆页面的提交按钮后执行的,boxid和boxpd分别是输入用户名和密码的textbox

[Copy to clipboard] [ - ]

CODE:

第一种,用户资料保存于数据库时

private void butlogin_Click(object sender, System.EventArgs e)

{

   if(islogin(boxid.Text,boxpd.Text))

     FormsAuthentication.RedirectFromLoginPage(boxid.Text,false);

   else

     Response.Write("error");

}

第二种,用户资料保存于web.config时

private void butlogin_Click(object sender, System.EventArgs e)

{

   if(FormsAuthentication.Authenticate(boxid.Text,boxpd.Text))

     FormsAuthentication.RedirectFromLoginPage(boxid.Text,false);

   else

     Response.Write("error");

}

这就是验证的基本过程。

而如果想要注销登陆,则用System.Web.Security的FormsAuthentication类的SignOut()方法

[Copy to clipboard] [ - ]

CODE:

private void butquit_Click(object sender, System.EventArgs e)

{

   FormsAuthentication.SignOut();

}

它返回一个Set-Cookie头,将Cookie的值设置为一个空字符串,并将Cookie的到器日期设置为一个过去的日期,从而有效销毁验证cookie。

而在实际情况下,您可能更愿意在顶层web.config文件中完成所有的url授权,而不是把它们分在各自目录下的web,config文件中。asp.net也支持这种做法。下面这个web,config文件,放在应用程序根目录下,它启用窗体验证并指定其他的一些设置。假设您要保护的文件夹名为protd。

[Copy to clipboard] [ - ]

CODE:

<configuration>

<system.web>

<authentication mode="Forms" >

<forms loginUrl="login.aspx">

<credentials passwordFormat="Clear">

<user name="notus" password="wei"/>

</credentials>

</forms>

</authentication>

</system.web>

<location path="protd">

<system.web>

<authorization>

<deny users="?"></deny>

</authorization>

</system.web>

</location>

</configuration>

注意它的层次结构,应该有两个<system.web>节。完成这个后,就可以把protd文件夹下的那个web.config删掉,然后看看效果如何。

基本的知识就这么多了,其实Forms验证还有很多内容,比如怎样以编程的方式改变永久性cookie的生存期,怎么使用基于角色的验证等,这些大家找相关资料研究研究吧。当然还是推荐上面说到的那本书,以前关于Forms验证的也看了不少资料,但总是不明白,结果昨天一看那本书的讲解,就豁然开朗了。

最后再给出我常用的一个islogin()代码。希望可以对初学者有些帮助。

[Copy to clipboard] [ - ]

CODE:

public bool islogin(string name,string password)

{

   bool isok=false;

   string errmsg="ok";

   StringBuilder sbsel=new StringBuilder();

   sbsel.Append("select name,password from youtable where name='");

   sbsel.Append(name);

   sbsel.Append("'");

   try

   {

      cmd=new OleDbCommand(sbsel.ToString(),conn);

      conn.Open();

      OleDbDataReader dr=cmd.ExecuteReader(CommandBehavior.SingleRow);

      if(dr.Read())

      {

         if(dr["password"].ToString()==password)

         isok=true;

      }

      errmsg="login is ok";

   }

   catch(OleDbException ex)

   {

      errmsg=ex.Message;

   }

   finally

   {

      conn.Close();

   }

   return isok;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多