最近开始一个小 asp.net 项目,整个项目需要登录才能操作。以前大家都采用 asp 的方式 session + cookie 来实现身份验证,我一直对 asp.net 自带的 forms 验证早就耳闻,苦于没实践,今天刚好逮到机会实际应用一下。
问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。
step 1: web.config 配置关键地方:

web.config配置 1
<!--
2
通过 <authentication> 节可以配置 ASP.NET 用来
3
识别进入用户的
4
安全身份验证模式。
5
-->
6
<authentication mode="Forms">
7
<forms loginUrl="login.aspx" defaultUrl="index.aspx"
8
name=".ztinfozero" path="/Manager"
9
slidingExpiration="true" timeout="10"></forms>
10
</authentication>
11
<authorization>
12
<deny users="?"/>
13
</authorization>
14
<!-- 实现自定义的 rolemanager 后需配置 :
<roleManager defaultProvider="providerName(类名)"
cookieName="role" cookiePath="/" enabled="true"
cookieTimeout="30" cookieSlidingExpiration="true"
cookieRequireSSL="false" cookieProtection="All"
cacheRolesInCookie="true">
<providers>
<clear />
<add name="providerName(类名)" type="providerName(类名)" />
</providers>
</roleManager>
-->
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(
1, 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 事件以设置当前登录用户的信息:

Application_AuthenticateRequest
/**//*****
using System;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
*****/

protected void Application_AuthenticateRequest(object sender, EventArgs e)

{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;

if (context.Request.IsAuthenticated)
{
FormsIdentity id = context.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = id.Ticket;
string[] roles = ticket.UserData.Split(',');

/**//*
* 将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户
* 这样当前用户就拥有了role信息
* 据此在web.config中用role来控制用户的访问权限了.
*/
context.User = new GenericPrincipal(id, roles);
}

old#region old

/**//*
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);
GenericPrincipal principal = new GenericPrincipal(id, roles);
Context.User = principal;
}
}
* */
#endregion
}

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

CurrentUser 
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();
}

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