View Javadoc

1   package org.springframework.security.config;
2   
3   import org.springframework.beans.factory.config.BeanDefinition;
4   import org.springframework.beans.factory.config.RuntimeBeanReference;
5   import org.springframework.beans.factory.parsing.BeanComponentDefinition;
6   import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
7   import org.springframework.beans.factory.support.BeanDefinitionBuilder;
8   import org.springframework.beans.factory.support.BeanDefinitionRegistry;
9   import org.springframework.beans.factory.support.RootBeanDefinition;
10  import org.springframework.beans.factory.xml.BeanDefinitionParser;
11  import org.springframework.beans.factory.xml.ParserContext;
12  import org.springframework.security.concurrent.ConcurrentSessionControllerImpl;
13  import org.springframework.security.concurrent.ConcurrentSessionFilter;
14  import org.springframework.security.concurrent.SessionRegistryImpl;
15  import org.springframework.security.providers.ProviderManager;
16  import org.springframework.util.StringUtils;
17  import org.w3c.dom.Element;
18  
19  /**
20   * Sets up support for concurrent session support control, creating {@link ConcurrentSessionFilter},
21   * {@link SessionRegistryImpl} and {@link ConcurrentSessionControllerImpl}. The session controller is also registered
22   * with the default {@link ProviderManager} (which is automatically registered during namespace configuration).
23   *
24   * @author Luke Taylor
25   * @version $Id: ConcurrentSessionsBeanDefinitionParser.java 3094 2008-05-27 13:14:21Z luke_t $
26   */
27  public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionParser {
28  
29      static final String ATT_EXPIRY_URL = "expired-url";
30      static final String ATT_MAX_SESSIONS = "max-sessions";
31      static final String ATT_EXCEPTION_IF_MAX_EXCEEDED = "exception-if-maximum-exceeded";
32      static final String ATT_SESSION_REGISTRY_ALIAS = "session-registry-alias";
33      static final String ATT_SESSION_REGISTRY_REF = "session-registry-ref";
34      
35      public BeanDefinition parse(Element element, ParserContext parserContext) {
36          CompositeComponentDefinition compositeDef =
37              new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
38          parserContext.pushContainingComponent(compositeDef);
39          
40          BeanDefinitionRegistry beanRegistry = parserContext.getRegistry();
41  
42          String sessionRegistryId = element.getAttribute(ATT_SESSION_REGISTRY_REF);
43          
44          if (!StringUtils.hasText(sessionRegistryId)) {            
45              RootBeanDefinition sessionRegistry = new RootBeanDefinition(SessionRegistryImpl.class);        
46              beanRegistry.registerBeanDefinition(BeanIds.SESSION_REGISTRY, sessionRegistry);
47              parserContext.registerComponent(new BeanComponentDefinition(sessionRegistry, BeanIds.SESSION_REGISTRY));
48              sessionRegistryId = BeanIds.SESSION_REGISTRY;
49          } else {
50              // Register the default ID as an alias so that things like session fixation filter can access it
51              beanRegistry.registerAlias(sessionRegistryId, BeanIds.SESSION_REGISTRY);
52          }
53  
54          String registryAlias = element.getAttribute(ATT_SESSION_REGISTRY_ALIAS);
55          if (StringUtils.hasText(registryAlias)) {
56              beanRegistry.registerAlias(sessionRegistryId, registryAlias);
57          }        
58  
59          BeanDefinitionBuilder filterBuilder =
60                  BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionFilter.class);
61          filterBuilder.addPropertyValue("sessionRegistry", new RuntimeBeanReference(sessionRegistryId));
62  
63          Object source = parserContext.extractSource(element);
64          filterBuilder.setSource(source);
65          filterBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
66  
67          String expiryUrl = element.getAttribute(ATT_EXPIRY_URL);
68  
69          if (StringUtils.hasText(expiryUrl)) {
70              ConfigUtils.validateHttpRedirect(expiryUrl, parserContext, source);
71              filterBuilder.addPropertyValue("expiredUrl", expiryUrl);
72          }        
73  
74          BeanDefinitionBuilder controllerBuilder
75              = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControllerImpl.class);
76          controllerBuilder.setSource(source);
77          controllerBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);        
78          controllerBuilder.addPropertyValue("sessionRegistry", new RuntimeBeanReference(sessionRegistryId));
79  
80          String maxSessions = element.getAttribute(ATT_MAX_SESSIONS);
81  
82          if (StringUtils.hasText(maxSessions)) {
83              controllerBuilder.addPropertyValue("maximumSessions", maxSessions);
84          }
85  
86          String exceptionIfMaximumExceeded = element.getAttribute(ATT_EXCEPTION_IF_MAX_EXCEEDED);
87  
88          if (StringUtils.hasText(exceptionIfMaximumExceeded)) {
89              controllerBuilder.addPropertyValue("exceptionIfMaximumExceeded", exceptionIfMaximumExceeded);
90          }
91  
92          BeanDefinition controller = controllerBuilder.getBeanDefinition();
93          
94          beanRegistry.registerBeanDefinition(BeanIds.CONCURRENT_SESSION_CONTROLLER, controller);
95          parserContext.registerComponent(new BeanComponentDefinition(controller, BeanIds.CONCURRENT_SESSION_CONTROLLER));
96          beanRegistry.registerBeanDefinition(BeanIds.CONCURRENT_SESSION_FILTER, filterBuilder.getBeanDefinition());
97          parserContext.registerComponent(new BeanComponentDefinition(filterBuilder.getBeanDefinition(), BeanIds.CONCURRENT_SESSION_FILTER));
98          ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.CONCURRENT_SESSION_FILTER));
99          
100         ConfigUtils.setSessionControllerOnAuthenticationManager(parserContext, BeanIds.CONCURRENT_SESSION_CONTROLLER, element);
101         
102         parserContext.popAndRegisterContainingComponent();
103         
104         return null;
105     }
106 }