使用HttpMoudle和IPrincipal實現自定義身份及權限認證

導讀:
  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);
  }
  }
  /// /// Log out the current user.註銷用戶
  ///
  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進行註冊
  
本文轉自
http://www.cnblogs.com/jecray/archive/2007/08/31/876594.html
發佈了23 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章