conan

导航

AOP应用之权限管理

在系统实现中AOP常用于并发、权限管理、事务处理、日志记录、错误处理方面。本文介绍如何使用EnterpriseServerBase类库中的AOP框架来实现权限管理。

一个用户是否有权限调用某个操作(方法),是由我们的应用决定了,不同的应用有不同的实现,但是,如果需要使用EnterpriseServerBase类库中的AOP的权限管理,则应用必须实现下面的接口IPermissionVerifier:

/// <summary>
    
/// IPermissionVerifier 用于验证当前用户对目标类的目标方法的调用权限是否足够。
    
/// 如果需要使用Aop来进行权限管理,则只要实现IPermissionVerifier接口。
    
/// 朱伟 2005.08.228
    
/// </summary>

    public interface IPermissionVerifier
    
{
        
bool QualifiedToOperation(object permissionNeeded ,string destClassFullName ,string destMethodName) ;
    }

当用户调用没有资格的操作时,将抛出PermissionLimittedException异常,其定义如下:

/// <summary>
    
/// 当没有权限的用户调用某项操作时,将抛出此异常
    
/// </summary>

    [Serializable]
    
public class PermissionLimittedException : Exception
    
{
        
public PermissionLimittedException()
        
{
        }


        
public PermissionLimittedException(string msg):base(msg)
        
{            
        }


        
public PermissionLimittedException(string msg ,Exception innerException) : base(msg ,innerException)
        
{            
        }

    }

接下来看真正实现权限AOP的PermissionProxy类:

/// <summary>
    
/// PermissionProxy 权限代理,如果当前用户不够权限调用某个方法,则抛出异常。
    
/// 朱伟 2005.08.22
    
/// </summary>

    public class PermissionProxy :AopProxyBase
    
{        
        
public PermissionProxy(MarshalByRefObject obj ,Type type ,object aopArg) : base(obj ,type ,aopArg)
        
{}

        
public override void PreProcess(IMethodCallMessage requestMsg)
        
{
            Type verifierType 
= (Type)this.AopClassArgument ;
            Type destType     
= typeof(IPermissionVerifier) ;
            
if(! destType.IsAssignableFrom(verifierType))
            
{
                
throw new Exception("the PermissionVerifierType is invalid !") ;
            }


            IPermissionVerifier pmVerifier 
= (IPermissionVerifier)Activator.CreateInstance(verifierType) ;
            
if(pmVerifier == null)
            
{
                
throw new Exception("the PermissionVerifierType is invalid !") ;
            }

            
            
object pmNeeded = this.GetAopMethodArgument((IMethodCallMessage)requestMsg) ;
            
string className  = AopHelper.GetFullClassName(requestMsg) ;
            
string methodName = AopHelper.GetMethodName(requestMsg) ;

            
bool qualified = pmVerifier.QualifiedToOperation(pmNeeded ,className ,methodName) ;

            
if(! qualified)
            
{
                
throw new PermissionLimittedException(string.Format("Current user have no permission to call dest method : {0}.{1}!" ,className ,methodName)) ;
            }


        }


        
public override void PostProcess(IMethodCallMessage requestMsg, IMethodReturnMessage Respond) 
        
{
            
        }

    }

    可以看出PermissionProxy是在预处理中进行权限鉴定的。关于其基类AopProxyBase的更多信息,可以参见前面的文章C# AOP微型框架实现(一)C# AOP微型框架实现(二) 。(注意,现在的AOP框架版本与参文中的介绍稍有出入!)

    另外,为了契合EnterpriseServerBase类库中的AOP框架,需要下面的工厂:

/// <summary>
    
/// PermissionProxyFactory 权限代理工厂。
    
/// 朱伟 2005.08.228
    
/// </summary>

    public class PermissionProxyFactory :IAopProxyFactory
    
{
        
#region IAopProxyFactory 成员

        
public AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type, object aopArg)
        
{
            
return new PermissionProxy(obj ,type ,aopArg) ;
        }


        
#endregion

    }

那么如何使用权限AOP了?

(1)根据目标系统对权限的管理需求实现IPermissionVerifier接口。
(2)在需要进行权限管理的类上加上特性[AopProxyAttribute(typeof(PermissionProxyFactory) ,typeof(PermissionVerifier))],
   其中PermissionVerifier是IPermissionVerifier实现。
(3)在需要进行权限管理的方法上加上特性[MethodAopSwitcherAttribute(true ,pmNeeded)],其中pmNeeded为调用此方法所需的资格,
   其类型由目标系统决定。

最后给出一个具体的例子说明:

[AopProxyAttribute(typeof(PermissionProxyFactory), Class1.verifier)]
    
public class Example :ContextBoundObject
    
{
        [MethodAopSwitcherAttribute(
true ,Permission.Super)]
        
public void SayHello(string name)
        
{
            Console.WriteLine(
"Hello ," + name) ;
        }


        [MethodAopSwitcherAttribute(
true ,Permission.Common)]
        
public void SayByebye(string name)
        
{
            Console.WriteLine(
"Byebye ," + name) ;
        }

    }


    

    
public class PermissionVerifier :IPermissionVerifier
    
{
        
#region IPermissionVerifier 成员

        
public bool QualifiedToOperation(object permissionNeeded, string destClassFullName, string destMethodName)
        
{
            Permission pm 
= (Permission)permissionNeeded ;
            
            
if(pm == Permission.Common)
            
{
                
return true ;
            }


            
return false;
        }


        
#endregion


    }


    
public enum Permission
    
{
        Common ,Super
    }

    
    [STAThread]
        
static void Main(string[] args)
        
{
            
try
            
{
                Example exa 
= new Example() ;                
                exa.SayByebye(
"sky") ;                    
                exa.SayHello(
"sky") ;
            }

            
catch(Exception ee)
            
{
                Console.WriteLine(ee.Message) ;
                Console.Read() ;
            }

        }

      如果需要例子的完整源码,可以email向我索取!也欢迎和我讨论关于AOP应用的更多技术。后面将会给出使用AOP进行日志记录的技术实现。

posted on 2005-08-23 21:34  Conan  阅读(2827)  评论(17编辑  收藏  举报