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

 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进行注册
分析代码来自Cuyahoga Created by jecray

你可能感兴趣的:(http)