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

来源:互联网 发布:淘宝推荐系统 研究 编辑:程序博客网 时间:2024/05/22 03:24
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
原创粉丝点击