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(); } 至此,身份验证完成 。我们不用费尽心思在四处堆放用户是否登录判断的代码了 。 |