asp.net forms身份验证,避免重复造轮子

  问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。

  step 1: web.config 配置关键地方:

  web.config配置

  

复制代码 代码如下:

  <!--

  通过 <authentication> 节可以配置 ASP.NET 用来

  识别进入用户的

  安全身份验证模式。

  -->

  <authentication mode="Forms">

  <forms loginUrl="login.aspx" defaultUrl="index.aspx"

  name=".ztinfozero" path="/Manager"

  slidingExpiration="true" timeout="10"></forms>

  </authentication>

  <authorization>

  <deny users="?"/>

  </authorization>

  step 2: 构造 SiteUser Model

  

复制代码 代码如下:

  TopicUser Model

  [Serializable]

  public class TopicUser

  {

  public TopicUser() { }

  model#region model

  private System.Int32 _autoID;

  /**//// <summary>

  ///

  /// </summary>

  public System.Int32 autoID

  {

  get { return _autoID; }

  set { _autoID = value; }

  }

  private System.String _UserName;

  /**//// <summary>

  /// 用户名

  /// </summary>

  public System.String UserName

  {

  get { return _UserName; }

  set { _UserName = value; }

  }

  private System.String _UserChName;

  /**//// <summary>

  /// 真实姓名

  /// </summary>

  public System.String UserChName

  {

  get { return _UserChName; }

  set { _UserChName = value; }

  }

  private System.String _UserPass;

  /**//// <summary>

  ///

  /// </summary>

  public System.String UserPass

  {

  get { return _UserPass; }

  set { _UserPass = value; }

  }

  private System.String _DepartMent;

  /**//// <summary>

  ///

  /// </summary>

  public System.String DepartMent

  {

  get { return _DepartMent; }

  set { _DepartMent = value; }

  }

  private System.String _Duty;

  /**//// <summary>

  ///

  /// </summary>

  public System.String Duty

  {

  get { return _Duty; }

  set { _Duty = value; }

  }

  private System.Int32 _UserPermit;

  /**//// <summary>

  ///

  /// </summary>

  public System.Int32 UserPermit

  {

  get { return _UserPermit; }

  set { _UserPermit = value; }

  }

  private System.Int32 _Status;

  /**//// <summary>

  ///

  /// </summary>

  public System.Int32 Status

  {

  get { return _Status; }

  set { _Status = value; }

  }

  #endregion

  }

  step 3: 创建用户登录代码:

  数据库-用户登录方法

  

复制代码 代码如下:

  public TopicUser UserLogon(string username, string pass) {

  string proc = "dbo.infozero_Proc_userLogOn";

  Database db = DataFactory.userDB;

  DbCommand cmd = db.GetStoredProcCommand(proc);

  db.AddInParameter(cmd, "@username", DbType.String, username);

  db.AddInParameter(cmd, "@userpass", DbType.String, pass);

  db.AddOutParameter(cmd, "@result", DbType.Int32, 4);

  DataSet ds = db.ExecuteDataSet(cmd);

  TopicUser user = null;

  int result = 0;

  if (int.TryParse(db.GetParameterValue(cmd, "@result").ToString(), out result) )

  user = tableToUser(ds.Tables[0]);

  return user;

  }

  #region table to user

  private TopicUser tableToUser(DataTable dt) {

  TopicUser model = null;

  if (dt.Rows.Count > 0) {

  model = new TopicUser();

  DataRow dr = dt.Rows[0];

  int aid = 0;

  int.TryParse(dr["autoID"].ToString(), out aid );

  model.autoID = aid;

  model.UserName = dr["UserName"].ToString();

  model.UserChName = dr["UserChName"].ToString();

  model.UserPass = dr["UserPass"].ToString();

  model.DepartMent = dr["DepartMent"].ToString();

  model.Duty = dr["Duty"].ToString();

  if (dr["UserPermit"].ToString() != "")

  {

  model.UserPermit = int.Parse(dr["UserPermit"].ToString());

  }

  if (dr["Status"].ToString() != "")

  {

  model.Status = int.Parse(dr["Status"].ToString());

  }

  }

  return model;

  }

  #endregion

  step 4 : 创建登录页:

  代码

  

复制代码 代码如下:

  protected void btnOK_Click(object sender, EventArgs e)

  {

  string username = tbname.Text.Trim();

  string pass = tbpass.Text.Trim();

  if (!string.IsNullOrEmpty(username)) {

  if (!string.IsNullOrEmpty(pass)) {

  DataService.User b = new DataService.User();

  DataService.TopicUser user = b.UserLogon(username, pass);

  if (user != null) {

  //roles , userid | userchname

  string userdata = string.Format("{0},{1}|{2}",

  user.UserPermit, user.autoID, user.UserChName);

  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(

  , username, DateTime.Now, DateTime.Now.AddHours(2),

  true, userdata);

  string encticket = FormsAuthentication.Encrypt(ticket);

  HttpCookie cookie = new HttpCookie(

  FormsAuthentication.FormsCookieName, encticket);

  Response.Cookies.Add(cookie);

  Response.Redirect("Index.aspx");

  }

  }

  }

  }

  step 5: 在 global.asax 里添加 Application_AuthenticateRequest 事件以设置当前登录用户的信息:

  

复制代码 代码如下:

  protected void Application_AuthenticateRequest(object sender, EventArgs e)

  {

  HttpCookie cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

  if (cookie != null) {

  FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

  if (ticket != null) {

  string[] roles = ticket.UserData.Split(',');

  FormsIdentity id = new FormsIdentity(ticket);

  System.Security.Principal.GenericPrincipal principal = new GenericPrincipal(id, roles);

  Context.User = principal;

  }

  }

  }

  step 6: 如何得到当前登录用户的信息

  

复制代码 代码如下:

  public static TopicUser CurrentUser {

  get {

  DataService.TopicUser user = new DataService.TopicUser();

  FormsIdentity identity = HttpContext.Current.User.Identity as FormsIdentity;

  FormsAuthenticationTicket ticket = identity.Ticket;

  string userdata = ticket.UserData; //获取自定义的 UserData 串

  if (!string.IsNullOrEmpty(userdata)) {

  if (userdata.IndexOf(',') > 0 && userdata.IndexOf('|') > 0)

  {

  //roles , userid | userchname

  string uinfo = userdata.Split(',')[1];

  string[] u = uinfo.Split('|');

  int uid = 0;

  int.TryParse(u[0], out uid);

  user.autoID = uid;

  user.UserChName = u[1];

  user.UserName = HttpContext.Current.User.Identity.Name;

  }

  }

  return user;

  }

  }

  由此得到当前登录用户的 ID 为 UserBase.CurrentUser.autoID ; 真实名字是: UserBase.CurrentUser.UserChName ;

  判断当前用户的角色是否为管理员: HttpContext.Current.User.IsInRole("1") ; // 1 为管理员

  退出当前登录的方法:

  LogOut.aspx

  

复制代码 代码如下:

  protected void Page_Load(object sender, EventArgs e)

  {

  System.Web.Security.FormsAuthentication.SignOut();

  Response.Write("<script>window.top.location='login.aspx';</script>");

  Response.End();

  }

  至此,身份验证完成。我们不用费尽心思在四处堆放用户是否登录判断的代码了。