Asp.Net 中中的Form验证

1. 网站为什么要验证

 

要想弄清楚这个问题,先得弄清楚网站的权限问题,有的页面匿名用户就可以看,譬如login页面,help页面等;

有些页面必须有权限才能看,譬如purchase页面;

还有些页面需要更高的权限才能看,譬如admin页面,configuration页面;

有些页面不同的人都可以看,但是不同类型的人看到的内容也不一样。

 

2. 解释几个名词,说清Form验证

 

为了解决这样的问题,我们先来解释三个词语

Identity: Who am I?  这个意思是我是谁,就是说通过identity(在asp.net Form验证中是HttpContext.Current.User.Identity.)可以识别当前用户是谁。你可能又有疑问,怎么忽然出来了一个HttpContext.Current.User.Identity,他怎么知道我是谁了,请看下面。

Authentication: This is Who am I? 这个问题是用来解决我是谁的,也就是说用户输入了用户名,密码后,通过Authentication可以确定用户是谁,并且让整个网站知道我是谁,它怎么做到的呢?细心的你可以注意到了FormsAuthentication,它提供了一个静态方法

 public static bool Authenticate(string name, string password);

你现在的问题可能是我都没有写到数据库验证的方法,都没有和数据库连接,我就传一个name和password,它就知道我是合法用户了?扯淡吧?的确是扯蛋,谁也没有通天的本领,任何事情都是一步一步来的。我们看一下这个方法的注释:

        //     Validates a user name and password against credentials stored in the configuration

 //     file for an application.

验证一个存储在web.config中对应于credentials这个节点中的用户名和密码,也就是说这个方法只是用来验证web.config中的用户名和密码,一般情况下,我们不会把用户名和密码存在那里,所有这个方法对于我们来说应该会比较少用。

那么真正是怎么验证的呢?肯定要访问数据库,和其中的数据进行比较,看是否是合法用户。既然这个Authenticate不能被我们所用,可以写一个我们自己的Authenticate方法,到数据库中进行验证,一般来说如果验证成功了的话,还需要做第三步,也就是下面要说的。

 

Authorization: What Can I do in this site? 这个意思是说我在这个网站的到底能够做些什么事情,换句话说就是有多少权限? 这个在网站中一般也是用户在Authenticate成功后,需要取出这个用户的所有权限,一般需要访问权限表,这样验证过程算是完成了。

 

既然90%以上的页面都需要进行验证,那么我么可以考虑加一个基类BasePage,所有需要验证的Form都继承这个基类,我们在基类的OnLoad方法中去进行做验证,这样就省了很多事情。

 

3. 还漏掉了那些事情

其实漏掉的事情还是很多的:

第一,  既然所有的页面都要验证,否则就直接近login页面,现在还不行,请在web.config 中的<system.web>节点中加入

<authentication mode="Forms">

    <forms  loginUrl = "Lonin.aspx" name = ".ASPXFORMSAUTH"/>

</authentication> 

第二,  有些页面不要验证怎么办,请在web.config 中加入

<location path="pagePath ">

    <system.web>

      <authorization>

        <allow users="*" />

      </authorization>

    </system.web>

</location>

第三,  如果我要记录住用户名,方便下次登录,或者甚至记住用户名和密码,下次自动登录,怎么做?

下面是一个实例,我们可以在写自己的Authenticate的方法的时候处理

///验证成功后我们讲用户名和密码已经用户的类别存在cookie中,保存期限是30天

  public bool Authenticate(string username, string password)

  {

UserInfo u = GetUserFromDB(username,password);

If(u==null){

          Return false;

}

Else{

WrieCookie(u);

Return true;

  }

                    }

                  

                   Public void WriteCookie(UserInfo u)

{

string m_userData = u.UserID.ToString()+","+u.UserName +","+u.UserType.ToString();

   FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(

    1,

    "WebbUser",

    System.DateTime.Now,

    System.DateTime.Now.AddDays(30),

    false,

    m_userData,

    "/");

   string encTicket = FormsAuthentication.Encrypt(ticket);

   HttpContext.Current.Response.Cookies.Add(new HttpCookie("WebbUser", encTicket));

}

                   虽然我们可以将这个Cookie保存在客户端30天,但是不用它保存了也没有用,也就是说我们需要在验证的时候先判断该用户是不是不需要登录的,如果是,那么直接返回true。怎么做呢?

 

 

protected UserInfo GetCookie()

  {

UserInfo u = null;

   if(User.Identity.IsAuthenticated)

   {

    string m_userData;

    FormsIdentity id = (FormsIdentity)User.Identity;

    FormsAuthenticationTicket ticket = id.Ticket;

    m_userData  = ticket.UserData;

    if(m_userData!=null)

    {

//将获取的user数据写到UserInfo中

     u = SetUserData(m_userData);

    }

   }

Return u;

  }

  private UserInfo SetUserData(string m_Data)

  {

   string[] m_string = m_Data.Split(new char[]{','});

UserInfo u = new UserInfo();

   if(m_string.Length==3)

   {

    u.UserID  = Convert.ToInt64(m_string[0]);

    u.UserName = m_string[1];

    u.UserType = PageHelper.ConvertToUserTypes(m_string[2]);

   }

Return u;

  }

                现在我们在修改一下Authenticate方法

  public bool Authenticate(string username, string password)

  {

UserInfo u = GetCookie();

If(u!=null){

Return true;

}else{

GetUserFromDB(username,password);

If(u==null){

          Return false;

}

Else{

WrieCookie(u);

Return true;

  }

}

                    }

 

                这样基本上就完成了整个Form验证, 当然使用过程自然还有不少细节问题,也不是一两句话可以说得清的,遇到问题多思考,看看google,找到答案应该也会很快。

posted @ 2008-10-24 16:16  做你所想  阅读(513)  评论(1)    收藏  举报