View Javadoc

1   package org.springframework.security.config;
2   
3   import java.util.Iterator;
4   import java.util.List;
5   
6   import org.apache.commons.logging.Log;
7   import org.apache.commons.logging.LogFactory;
8   import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
9   import org.springframework.beans.factory.config.BeanDefinition;
10  import org.springframework.beans.factory.config.BeanDefinitionHolder;
11  import org.springframework.beans.factory.config.RuntimeBeanReference;
12  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
13  import org.springframework.beans.factory.support.RootBeanDefinition;
14  import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
15  import org.springframework.beans.factory.xml.ParserContext;
16  import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
17  import org.springframework.util.StringUtils;
18  import org.springframework.util.xml.DomUtils;
19  import org.w3c.dom.Element;
20  import org.w3c.dom.Node;
21  
22  /**
23   * @author Luke Taylor
24   * @author Ben Alex
25   *
26   * @version $Id: InterceptMethodsBeanDefinitionDecorator.java 2790 2008-03-24 09:40:13Z benalex $
27   */
28  public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDecorator {
29      private BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator();
30  
31      public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
32          ConfigUtils.registerProviderManagerIfNecessary(parserContext);
33          ConfigUtils.registerDefaultAccessManagerIfNecessary(parserContext);
34          
35          return delegate.decorate(node, definition, parserContext);
36      }
37  }
38  
39  /**
40   * This is the real class which does the work. We need access to the ParserContext in order to do bean
41   * registration.
42   */
43  class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
44      static final String ATT_METHOD = "method";
45      static final String ATT_ACCESS = "access";
46      private static final String ATT_ACCESS_MGR = "access-decision-manager-ref";
47  
48      private Log logger = LogFactory.getLog(getClass());
49  
50      protected BeanDefinition createInterceptorDefinition(Node node) {
51          Element interceptMethodsElt = (Element)node;
52          BeanDefinitionBuilder interceptor = BeanDefinitionBuilder.rootBeanDefinition(MethodSecurityInterceptor.class);
53  
54          // Default to autowiring to pick up after invocation mgr
55          interceptor.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
56  
57          String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR);
58  
59          if (!StringUtils.hasText(accessManagerId)) {
60              accessManagerId = BeanIds.ACCESS_MANAGER;
61          }
62  
63          interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
64          interceptor.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
65  
66          // Lookup parent bean information
67          Element parent = (Element) node.getParentNode();
68          String parentBeanClass = parent.getAttribute("class");
69          String parentBeanId = parent.getAttribute("id");
70          parent = null;
71          
72          // Parse the included methods
73          List methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
74  
75          StringBuffer sb = new StringBuffer();
76          
77          for (Iterator i = methods.iterator(); i.hasNext();) {
78              Element protectmethodElt = (Element) i.next();
79              String accessConfig = protectmethodElt.getAttribute(ATT_ACCESS);
80  
81              // Support inference of class names
82              String methodName = protectmethodElt.getAttribute(ATT_METHOD);
83              
84              if (methodName.lastIndexOf(".") == -1) {
85                  if (parentBeanClass != null && !"".equals(parentBeanClass)) {
86                      methodName = parentBeanClass + "." + methodName;
87                  }
88              }
89              
90              // Rely on the default property editor for MethodSecurityInterceptor.setObjectDefinitionSource to setup the MethodDefinitionSource
91              sb.append(methodName + "=" + accessConfig).append("\r\n");
92          }
93          
94          interceptor.addPropertyValue("objectDefinitionSource", sb.toString());
95  
96          return interceptor.getBeanDefinition();
97      }
98  }