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
21
22
23
24
25
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
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 }