ASP.NET 深入探讨 Forms 验证

1.受Forms验证保护的对象
Forms验证只保护asp.net文件。他保护注册到asp.net的aspx文件、asmx文件及其他文件,但是不保护不属于asp.net的文件-如,文件扩展名为.htm或.html的文件。因为asp.net从来看不到对没有注册到它的文件的请求。
2.web.config的location节
使用location节可以很容易的在根目录下的web.config设置整个应用程序的保护范围。下面是一个示例。
<location path="secret">
<system.web>
<authorization>
<allow roles="coder,manager"></allow>
<deny users="*"/>
</authorization>
</system.web>
</location>

<location path="secret/manage.aspx">
<system.web>
<authorization>
<allow roles="manager"></allow>
<deny users="*"/>
</authorization>
</system.web>
</location>

<location path="coo.aspx">
<system.web>
<authorization>
<allow roles="coder"></allow>
<deny users="*"></deny>
</authorization>
</system.web>
</location>

使用location节来指定了三个不同的保护措施,其中secret/manage.aspx是在secret的保护级别里又加了一层。
3.自由设定验证cookie的超时时间。
在FormsAuthentication.SetAuthCookie(string,bool)方法中,有个参数可以设定验证cookie是临时的还是永久的,如是false,就是临时,时间按web,config中的设定时间来算。如果true,那就是永久的,默认值为50年(……),但是我们可以通过编程的方式来改变这个数字,这就实现了很多地方有“选择cookie保留时间”的功能。
//给用户添加验证凭证
FormsAuthentication.SetAuthCookie(username.Text,true);
//获取验证cookie,FormsAuthentication.FormsCookieName的值就是cookie的name默认是.ASPXAUTH,可以在web.config更改
HttpCookie coo=Response.Cookies[FormsAuthentication.FormsCookieName];
//根据用户对RadioButtonList的选择改变cookie的超时时间
switch(timeout.SelectedValue)
{
   case "1" :
   coo.Expires=DateTime.Now+new TimeSpan(0,0,1,0);
   break;
   case "10" :
   coo.Expires=DateTime.Now+new TimeSpan(0,0,10,0);
   break;
   case "60" :
   coo.Expires=DateTime.Now+new TimeSpan(0,0,60,0);
   break;
   default :
   coo.Expires=DateTime.Now+new TimeSpan(0,0,1,0);
   break;
}

4.获取用户信息
这个问题就是,通过Forms验证后,怎么才能得到用户名。其实也简单,通过Page的User属性来完成这个任务。User属性返回一个IPrincipal对象,然后IPrincipal有个Identity属性,可以获取当前用户的标识。
再说一下这个User,是为当前 HTTP 请求获取或设置安全信息。HttpContext.User 属性提供对 IPrincipal接口的属性和方法的编程访问。
IPrincipal对象,表示代码为其运行的用户的安全上下文,包括用户的标识和任何它们所属的角色。
//IPrincipal接口的属性Identity
Response.Output.Write(Page.User.Identity.Name+"<br>");
Response.Output.Write(Page.User.Identity.AuthenticationType+"<br>");
Response.Output.Write(Page.User.Identity.IsAuthenticated+"<br>");

//IPrincipal接口的方法IsInRole
Response.Write(Page.User.IsInRole("manager"));
5.使用角色。
上面演示location节时用的验证方法都是基于角色的验证。角色这个词可以参照mssql里的角色,就是一系列不同的权限,比如只有角色是manager的人才可以查看secret/manage.aspx
具体用法就是在定义用户的同时添加一个role字段,这个字段为该拥护分配角色。然后在进行验证的时候通过Global.asax的Application_AuthenticateRequest事件在用户验证时将该用户的角色添加到用户凭证中,最后web.config根据用户的角色判断该用户是否有权力查看相应的页面。
注意我这里说的是把用户资料存在数据库中的情况。下面的代码放在Global.asax.cs文件中。
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
  
//获得当前HttpApplication,定义 ASP.NET 应用程序中的所有应用程序对象通用的方法、属性和事件。
   HttpApplication app=(HttpApplication)sender;
  
//检查用户是否通过了验证及验证类型是否为forms验证
   if(app.Request.IsAuthenticated && app.User.Identity is FormsIdentity)
   {
     
//将当前用户的身份转成formsidentity
      FormsIdentity fid=(FormsIdentity)app.User.Identity;
     
//获取该用户的角色
      string role=getRole(fid.Name);
     
//通过设置GenericPrincipal,来将roles添加到当前用户。GenericPrincipal:此类表示当前用户的角色。
      if(role!=null)
         app.Context.User=new GenericPrincipal(fid,new string[] {role});
   }
}

//获取用户的角色
private string getRole(string name)
{
   string strconn=ConfigurationSettings.AppSettings[0];
   SqlConnection conn=new SqlConnection(strconn);
   string sql="select role from users where username= @username";
   SqlCommand cmd=new SqlCommand(sql,conn);
   SqlParameter uname=new SqlParameter("@username",SqlDbType.VarChar,50);
   uname.Value=name;
   cmd.Parameters.Add(uname);
   try
   {
      conn.Open();
      object role=cmd.ExecuteScalar();
      if(role is DBNull)
      return null;
      return (string)role;
   }
   catch(SqlException)
   {
      return null;
   }
   finally
   {
      conn.Close();
   }
}

比如说username:Notus/password:wei/role:coder。该用户在登陆时对其进行Forms验证,如通过,则给其设定验证凭据,同时Application_AuthenticateRequest事件启动,在该凭据内加入用户的角色信息,在这里为coder。这样用户可以访问coo.aspx,因其角色为coder,也可以访问secret中的文件,但是不可以访问secret/manage.aspx,因为按web.config的设定,只有角色为manager的才可以访问该文件。
6.用户合法性验证
下面是我常用的代码,顺便贴出来。
public bool check(string uid,string pwd)
{
   string strconn=ConfigurationSettings.AppSettings[0];
   SqlConnection conn=new SqlConnection(strconn);
   string sql="select password from users where username=@username";
   SqlCommand cmd=new SqlCommand(sql,conn);
   SqlParameter uname=new SqlParameter("@username",SqlDbType.VarChar,50);
   uname.Value=uid;
   cmd.Parameters.Add(uname);
   try
   {
      conn.Open();
      object password=cmd.ExecuteScalar();
      if(password is DBNull)
         return false;
      if((string)password!=pwd)
         return false;
      return true;
   }
   catch(SqlException ex)
   {
      return false;
   }
   finally
   {
      conn.Close();
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值