Asp.Net实现FORM认证的一些使用技巧(必看篇)

2019-05-22 12:11:31于丽

2、手工实现需要记录用户登录信息的情况

当我们需要记录用户登录的信息,不单单只是一个ID还需要更多属性的时候,一般都用一个类存储到Session或Cookie实现,然后做一个基类页,在基类页中设置属性来读取Session或Cookie。

Session实际也和支不支持Cookie有关,且存在服务器,多少会占用服务器端资源。因此这里还是考虑用Cookie实现。那么在RedirectFromLoginPage方法或SetAuthCookie方法已经设置了验证票据并设置了Cookie,我们能不能把用户登录信息也存储到这个默认的Cookie里呢?答案是能。

首先,我们在项目里添加AppCode目录,增加一个UserInfo的类,用以简单模拟用户登录信息。代码如下:

[Serializable]
public class UserInfo
{
  //用户登录信息
  private int _nId;
  private string _sRealName;
  private string _sName;  
  private string _sPassword;
  private string _sRoles;

  public int Id
  {
    get { return this._nId; }
    set { this._nId = value; }
  }
  public string RealName
  {
    get { return this._sRealName; }
    set { this._sRealName = value; }
  }
  public string Name
  {
    get { return this._sName; }
    set { this._sName = value; }
  }
  public string Password
  {
    get { return this._sPassword; }
    set { this._sPassword = value; }
  }
  public string Roles
  {
    get { return this._sRoles; }
    set { this._sRoles = value; }
  }

  public UserInfo()
  {    
  }
}

需要注意, 类的属性中一定要加[Serializable],表示类可以序列化。

Forms验证在内部的机制是,把用户数据加密后保存在一个基于cookie的票据FormsAuthenticationTicket中,通过RedirectFromLoginPage方法或SetAuthCookie方法就已经实现了Ticket和Cookie的设置,也就是设置了Context.User的值,Context.User在取值和判断是否经过验证的时候很有用处。Cookie的属性是在Web.config的<forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" path="/" timeout="20"/>中设置的。因为是经过特殊加密的,所以应该来说是比较安全的。

而.net除了用这个票据存放自己的信息外,还留了一个地给用户自由支配,这就是现在要说的Ticket的UserData。 UserData用来存储string类型的信息,并且也享受Forms验证提供的加密保护,当我们需要这些信息时,也可以通过简单的Ticket的 UserData属性得到,兼顾了安全性和易用性,用来保存一些必须的敏感信息还是很有用的。我们就准备将用户的登录信息记录在UserData中,代码如下:

protected void Button1_Click(object sender, EventArgs e)
  {
    if (this.TextBox1.Text == "Admin" && this.TextBox2.Text == "123456")
    {
      // 加密UserInfo
      UserInfo user = new UserInfo();
      user.Id = 1;
      user.Name = this.TextBox1.Text;
      user.Password = this.TextBox2.Text;
      user.RealName = "系统管理员";
      user.Roles = "Administrators,Users";
      string strUser = Serialize.Encrypt<UserInfo>(user);

      // 设置Ticket信息
      FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
        1, user.Name, DateTime.Now, DateTime.Now.AddMinutes(20), false, strUser);

      // 加密验证票据
      string strTicket = FormsAuthentication.Encrypt(ticket);

      // 使用新userdata保存cookie
      HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strTicket);
      cookie.Expires = ticket.Expiration;
      this.Response.Cookies.Add(cookie);
      

      this.Response.Redirect("Default.aspx");
    }
}