andyj2ee

java tec sky

统计

留言簿(4)

activemq

aop

design pattern

other blog

spring

workflow

多线程

软件架构师

阅读排行榜

评论排行榜

基于spring aop 权限管理系统原型<2>

111-spring_aop.gif
    此权限管理系统把待访问的业务层方法做为权限管理中的资源,通过spring aop 对接口方法进行拦截,来实现权限的管理,可以实现细粒度的权限控制。
在上文体验了spring aop 一些特性,aop 接口:MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice 实现这三个接口分别对方法执行前,后,执行中抛异常等情况进行的,我们要是想做overload 这样的操作时,要用MethodInterceptor 接口,此接口好在有返回值,

public Object invoke(
      MethodInvocation invocation) 
      throws Throwable
   
{
//.
}


上文做法有些牵强业务逻辑还有throws PermissionDeniedException 感觉不爽,现在用MethodInterceptor 接口,来写这个demo,把权限与业务分开。
advice 如下:

public class PermissionCheckAroundAdvice implements MethodInterceptor {
    SecurityManager securityMgr 
= new SecurityManager();
    
    
/**
     * @param securityMgr The securityMgr to set.
     
*/

    
public void setSecurityMgr(SecurityManager securityMgr) {
        
this.securityMgr = securityMgr;
    }

    
public Object invoke(MethodInvocation invocation) throws Throwable {
        System.
out.println("(被调用方法接口类名: "
                
+ invocation.getMethod().getDeclaringClass().getName() + ")");
        System.
out.println("(被调用方法名:" + invocation.getMethod().getName()+ ")");
        String methodName 
= invocation.getMethod().getDeclaringClass()
                .getName() 
+ "." + invocation.getMethod().getName();
        System.
out.println("(被调用方法全名:" + methodName + ")");
        System.
out.println("有否权限:(" + securityMgr.checkPermission(methodName)+ ")");
        
if(securityMgr.checkPermission(methodName))
            
return invocation.proceed();
         System.
out.println("Goodbye! NO Permission!(by " + this.getClass().getName() + ")");
        
return "--";
    }

}

服务层业务接口修改如下:

public interface Service {
    
public String getBeanInfo();
}

服务层业务实现类如下:

public class ServiceBean implements Service {
    ResourceBean bean;

    
/**
     * @param bean The bean to set.
     
*/

    
public void setBean(ResourceBean bean) {
        
this.bean = bean;
    }

    
public String getBeanInfo(){
        String result
="";
        
        result
+= bean.getMethod1();
        result
+= bean.getMethod2();
        result
+= bean.getMethod3();
        
return result;
    }


}

资源层,接口 ,类如下:

public interface Resource {
}

 

public interface ResourceBean extends Resource{
    
public void theMethod();
    
public String getMethod1();
    
public String getMethod2();
    
public String getMethod3();
}

 

public class ResourceBeanImpl implements ResourceBean,InitializingBean{

    
public void theMethod(){
        System.
out.println(this.getClass().getName()
                
+ "." + new Exception().getStackTrace()[0].getMethodName()
                
+ "()"
                
+ " says HELLO!");
    }


    
public String getMethod1(){
        
return "张三";
    }


    
public String getMethod2(){
        
return "李四";
    }


    
public String getMethod3(){
        
return "王五";
    }


    
public void afterPropertiesSet() throws Exception {
        System.
out.println("事件监听:类ResourceBeanImpl属性设置完毕");
        
    }


}

权限管理类:

public class User {
    List privilages 
= new java.util.ArrayList();
    String name;
    
public User(){
    }

    
    
/**
     * @param privilages The privilages to set.
     
*/

    
public void setPrivilages(List privilages) {
        
this.privilages = privilages;
    }

    
public String getName(){
        
return name;
    }

    
public void setName(String name){
        
this.name=name;
    }

    
public boolean isPermission(String pri){
        java.util.Iterator it 
= privilages.iterator();
        String p 
= "";
        boolean pass
=false;
        
while(it.hasNext()){
            
            p
=(String)it.next();
            System.
out.println(p);
            
if(p.equals(pri)){
                pass 
= true;
                
break;
            }

        }

        
return pass;
    }


}

 

public class SecurityManager {
    User user;
    
public void setUser(User user){
        
this.user = user;
    }

    
public boolean checkPermission(String privilege){
        
return checkPermission(user,privilege);
    }

    
public boolean checkPermission(User user, String privilege){
        
return user.isPermission(privilege);
    }


}



配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
  
<!--CONFIG-->
  
<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
    
<property name="proxyInterfaces">
      
<value>com.jhalo.jsecurity.aop.ResourceBean</value>
    
</property>
    
<property name="target">
      
<ref local="beanTarget"/>
    
</property>
    
<property name="interceptorNames">
      
<list>
        
<value>permissionAroundAdvisor</value>
      
</list>
    
</property>
  
</bean>
  
<bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
    
<property name="proxyInterfaces">
      
<value>com.jhalo.jsecurity.aop.Service</value>
    
</property>
    
<property name="target">
      
<ref local="serviceBean"/>
    
</property>
    
<property name="interceptorNames">
      
<list>
        
<value>permissionAroundAdvisor</value>
      
</list>
    
</property>
  
</bean>

  
<!--CLASS-->
  
<bean id="resourceMgr" class="com.jhalo.jsecurity.aop.ResourceManager"/>
  
<bean id="beanTarget" class="com.jhalo.jsecurity.aop.ResourceBeanImpl"/>
  
<bean id="beanTarget2" class="com.jhalo.jsecurity.aop.ResourceBean2Impl"/>
  
<bean id="user" class="com.jhalo.jsecurity.aop.User">
      
<property name="name">
          
<value>tester</value>
      
</property>
      
<property name="privilages">
        
<list>
            
<value>com.jhalo.jsecurity.aop.ResourceBean.getMethod3</value>
            
<value>com.jhalo.jsecurity.aop.Service.getBeanInfo</value>
            
<value>com.jhalo.jsecurity.aop.ResourceBean.getMethod1</value>
        
</list>
    
</property>
  
</bean>
  
<bean id="securityMgr" class="com.jhalo.jsecurity.aop.SecurityManager">
      
<property name="user">
        
<ref local="user"/>
      
</property>
  
</bean>
  
  
<bean id="serviceBean" class="com.jhalo.jsecurity.aop.ServiceBean">
      
<property name="bean">
        
<!-- <ref local="beanTarget"/>-->
        
<ref local="bean"/>
      
</property>
  
</bean>
  
  
  
<!--ADVISOR-->
  
<!--Note: An advisor assembles pointcut and advice-->
  
<!--  -->
  
<!-- permission around advisor -->
  
<bean id="permissionAroundAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        
<property name="advice">
            
<ref local="thePermissionAroundAdvice"/>
        
</property>
        
<property name="pattern">
            
<value>.*</value>
        
</property>
  
</bean>

  
<!--ADVICE-->
  
<bean id="thePermissionCheckBeforeAdvice" class="com.jhalo.jsecurity.aop.PermissionCheckAdvice"/>
  
<bean id="thePermissionThrowsAdvice" class="com.jhalo.jsecurity.aop.PermissionThrowsAdvice"/>
  
<bean id="thePermissionAroundAdvice" class="com.jhalo.jsecurity.aop.PermissionCheckAroundAdvice">
      
<property name="securityMgr">
        
<ref local="securityMgr"/>
    
</property>
  
</bean>
</beans>

User 所拥有的权限是在spring 配置文件中手工配置的,在实际应用中不可行,可以从DB中取得。

测试类:

public class SpringAopTest {
    
public static void main(String[] args) {
        
//Read the configuration file
        ApplicationContext ctx
            
= new FileSystemXmlApplicationContext("springconfig.xml");
String name 
= "";
Service sb 
= (Service)ctx.getBean("service");
//        System.out.println("---"+ctx.isSingleton("service")+"---");
        name = sb.getBeanInfo();
        System.
out.println("test result::" +name);
      }


}



测试结果 :

(xml.XmlBeanDefinitionReader         119 ) Loading XML bean definitions from file [D:\projects\actives\jsecurity\springconfig.xml]
(support.FileSystemXmlApplicationContext 
90  ) Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=25853693]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [bean,service,resourceMgr,beanTarget,beanTarget2,user,securityMgr,serviceBean,permissionAroundAdvisor,thePermissionCheckBeforeAdvice,thePermissionThrowsAdvice,thePermissionAroundAdvice]; root of BeanFactory hierarchy
(support.FileSystemXmlApplicationContext 
287 ) 12 beans defined in application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=25853693]
(support.FileSystemXmlApplicationContext 
395 ) Unable to locate MessageSource with name 'messageSource'using default [org.springframework.context.support.StaticMessageSource: {}]
(support.FileSystemXmlApplicationContext 
417 ) Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster'using default [org.springframework.context.event.SimpleApplicationEventMulticaster@5e5a50]
(support.FileSystemXmlApplicationContext 
439 ) Refreshing listeners
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'resourceMgr'
(support.FileSystemXmlApplicationContext 
448 ) Application listener [com.jhalo.jsecurity.aop.ResourceManager@a3d4cf] added
(support.DefaultListableBeanFactory  
221 ) Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [bean,service,resourceMgr,beanTarget,beanTarget2,user,securityMgr,serviceBean,permissionAroundAdvisor,thePermissionCheckBeforeAdvice,thePermissionThrowsAdvice,thePermissionAroundAdvice]; root of BeanFactory hierarchy]
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'bean'
(core.CollectionFactory              
55  ) Using JDK 1.4 collections
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'beanTarget'
事件监听:类ResourceBeanImpl属性设置完毕
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'permissionAroundAdvisor'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'thePermissionAroundAdvice'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'securityMgr'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'user'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'service'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'serviceBean'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'beanTarget2'
事件监听:类ResourceBean2Impl属性设置完毕
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'thePermissionCheckBeforeAdvice'
(support.DefaultListableBeanFactory  
236 ) Creating shared instance of singleton bean 'thePermissionThrowsAdvice'
--------ContextRefreshedEvent called
(被调用方法接口类名: com.jhalo.jsecurity.aop.Service)
(被调用方法名:getBeanInfo)
(被调用方法全名:com.jhalo.jsecurity.aop.Service.getBeanInfo)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
有否权限:(
true)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
(被调用方法接口类名: com.jhalo.jsecurity.aop.ResourceBean)
(被调用方法名:getMethod1)
(被调用方法全名:com.jhalo.jsecurity.aop.ResourceBean.getMethod1)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
com.jhalo.jsecurity.aop.ResourceBean.getMethod1
有否权限:(
true)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
com.jhalo.jsecurity.aop.ResourceBean.getMethod1
(被调用方法接口类名: com.jhalo.jsecurity.aop.ResourceBean)
(被调用方法名:getMethod2)
(被调用方法全名:com.jhalo.jsecurity.aop.ResourceBean.getMethod2)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
com.jhalo.jsecurity.aop.ResourceBean.getMethod1
有否权限:(
false)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
com.jhalo.jsecurity.aop.Service.getBeanInfo
com.jhalo.jsecurity.aop.ResourceBean.getMethod1
Goodbye
! NO Permission!(by com.jhalo.jsecurity.aop.PermissionCheckAroundAdvice)
(被调用方法接口类名: com.jhalo.jsecurity.aop.ResourceBean)
(被调用方法名:getMethod3)
(被调用方法全名:com.jhalo.jsecurity.aop.ResourceBean.getMethod3)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
有否权限:(
true)
com.jhalo.jsecurity.aop.ResourceBean.getMethod3
test result::张三
--王五

这样就完全把企业业务逻辑与权限管理系统分开了,服务层,资源层与权限检查分离,用spring aop 通过配置文件把它们粘合在一起。实现了细粒度(对资源层数据)的权限检查。

 接下来在此权限管理系统中引用角色概念,向 rbac 系统进军.(未完待续) 

参考资料:
An Introduction to Aspect-Oriented Programming with the Spring Framework, Part 1 by Russell Miles -- The Spring framework, which supports development of the different facets of J2EE, provides an aspect-oriented programming module that gives Spring developers the opportunity to apply aspects to their applications. This article shows you how to work with AOP in Spring.
An Introduction to Aspect-Oriented Programming with the Spring Framework, Part 2 by Russell Miles -- Russ Miles continues his introduction to Aspect-Oriented Programming (AOP) in Spring by delving into the around advice, which allows you to not just add to an existing method implementation, but to completely replace it.


 


 



方向:分布式系统设计

posted on 2005-04-08 15:15 java光环 阅读(6113) 评论(1)  编辑  收藏 所属分类: spring

评论

# re: 基于spring aop 权限管理系统原型 2008-06-10 11:37 苦闷

<bean id="user" class="com.jhalo.jsecurity.aop.User">
<property name="name">
<value>tester</value>
</property>
<property name="privilages">
<list>
<value>com.jhalo.jsecurity.aop.ResourceBean.getMethod3</value>
<value>com.jhalo.jsecurity.aop.Service.getBeanInfo</value>
<value>com.jhalo.jsecurity.aop.ResourceBean.getMethod1</value>
</list>
</property>
</bean>


======================
这个东西是动态的哟。不能写死啊!
通过什么方法可以得到咧?  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: