您的位置:首页 > 理论基础 > 计算机网络

使用HttpMoudle和IPrincipal实现自定义身份及权限认证

2008-10-31 16:54 736 查看
HttpContext.Current.User用户对象表示用户的安全上下文,代码当前即以该用户的名义运行,包括用户的标识(IIdentity)和它们所属的任何角色。所有用户对象都需要实现 IPrincipal 接口。(MSDN)

创建一个User类实现IIdentity接口 重写相应的方法

public class User : IIdentity

{

private int _id;

private string _userName;

private string _password;

private bool _isAuthenticated;

#region properties

public virtual int Id

{

get { return this._id; }

set { this._id = value; }

}

public virtual string UserName

{

get { return this._userName; }

set { this._userName = value; }

}

public virtual string Password

{

get { return this._password; }

set { this._password = value; }

}

//是否通过认证

public virtual bool IsAuthenticated

{

get { return this._isAuthenticated; }

set { this._isAuthenticated = value; }

}

//重写为用户ID

public virtual string Name

{

get

{

if (this._isAuthenticated)

return this._id.ToString();

else

return "";

}

}

public virtual string AuthenticationType

{

get { return "CuyahogaAuthentication"; }

}

public User()

{

this._id = -1;

this._isAuthenticated = false;

}

}

创建一个CuyahogaPrincipal类实现IPrincipal接口

public class CuyahogaPrincipal : IPrincipal

{

private User _user;

// 返回一个现实IIdentity接口的user对象

public IIdentity Identity

{

get { return this._user; }

}

// 当前用户是否属于指定角色 在以后的权限认证中可以使用 也可以使用User类中的相关方法来代替

public bool IsInRole(string role)

{

foreach (Role roleObject in this._user.Roles)

{

if (roleObject.Name.Equals(role))

return true;

}

return false;

}

///初始化 若user通过授权则创建

public CuyahogaPrincipal(User user)

{

if (user != null && user.IsAuthenticated)

{

this._user = user;

}

else

{

throw new SecurityException("Cannot create a principal without u valid user");

}

}

}

创建一个实现IHttpModule的AuthenticationModule类

public class AuthenticationModule : IHttpModule

{

private const int AUTHENTICATION_TIMEOUT = 20;

public AuthenticationModule()

{

}

public void Init(HttpApplication context)

{

context.AuthenticateRequest += new EventHandler(Context_AuthenticateRequest);

}

public void Dispose()

{

// Nothing here

}

//登录时 验证用户时使用

public bool AuthenticateUser(string username, string password, bool persistLogin)

{

//数据访问类

CoreRepository cr = (CoreRepository)HttpContext.Current.Items["CoreRepository"];

string hashedPassword = Encryption.StringToMD5Hash(password);

try

{

//通过用户名密码得到用户对象

User user = cr.GetUserByUsernameAndPassword(username, hashedPassword);

if (user != null)

{

user.IsAuthenticated = true;

//string currentIp = HttpContext.Current.Request.UserHostAddress;

//user.LastLogin = DateTime.Now;

//user.LastIp = currentIp;

// Save login date and IP 记录相关信息

cr.UpdateObject(user);更新用户授权通过信息

// Create the authentication ticket

HttpContext.Current.User = new CuyahogaPrincipal(user); //通过授权

FormsAuthentication.SetAuthCookie(user.Name, persistLogin);

return true;

}

else

{

//log.Warn(String.Format("Invalid username-password combination: {0}:{1}.", username, password));

return false;

}

}

catch (Exception ex)

{

throw new Exception(String.Format("Unable to log in user '{0}': " + ex.Message, username), ex);

}

}

/// <summary>

/// Log out the current user.注销用户

/// </summary>

public void Logout()

{

if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)

{

FormsAuthentication.SignOut();

}

}

private void Context_AuthenticateRequest(object sender, EventArgs e)

{

HttpApplication app = (HttpApplication)sender;

if (app.Context.User != null && app.Context.User.Identity.IsAuthenticated)//若用户已经通过认证

{

CoreRepository cr = (CoreRepository)HttpContext.Current.Items["CoreRepository"];

int userId = Int32.Parse(app.Context.User.Identity.Name);

User cuyahogaUser = (User)cr.GetObjectById(typeof(User), userId);//得到对应的cuyahogaUser对象

cuyahogaUser.IsAuthenticated = true;

app.Context.User = new CuyahogaPrincipal(cuyahogaUser);//将通过标准窗体认证的user替换成CuyahogaUser, cuyahogaUser包含更多的信息

}

}

}

登录时

protected void btnLogin_Click(object sender, System.EventArgs e)

{

AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"];

if (this.txtUsername.Text.Trim().Length > 0 && this.txtPassword.Text.Trim().Length > 0)

{

try

{

if (am.AuthenticateUser(this.txtUsername.Text, this.txtPassword.Text, this.chkPersistLogin.Checked))

{

//通过认证

Context.Response.Redirect(Context.Request.RawUrl);

}

else

{

//认证失败

}

}

catch (Exception ex)

{

}

}

}

退出登录用

protected void btnLogout_Click(object sender, System.EventArgs e)

{

AuthenticationModule am = (AuthenticationModule)Context.ApplicationInstance.Modules["AuthenticationModule"];

am.Logout();

Context.Response.Redirect(Context.Request.RawUrl);

}

这样就实现了身份认证功能

然后可以方便的实现权限认证

在User类中实现相应的权限逻辑 如: 表示当前用户是否有权限浏览指定的节点
public bool CanView(Node node)

{

foreach (Permission p in node.NodePermissions)

{

if (p.ViewAllowed && IsInRole(p.Role))

{

return true;

}

}

return false;

}

在Page代码中嵌入验证代码即可

User CuyahogaUser = this.User.Identity as User;

if(CuyahogaUser.CanView())

{

}
权限认证模块还是挺简单.

别忘了在web.config中对AuthenticationModule进行注册

分析代码来自CuyahogaCreated by jecray
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: