1 package org.springframework.security.config;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.springframework.beans.BeanMetadataElement;
9 import org.springframework.beans.MutablePropertyValues;
10 import org.springframework.beans.PropertyValue;
11 import org.springframework.beans.factory.config.BeanDefinition;
12 import org.springframework.beans.factory.config.RuntimeBeanReference;
13 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
14 import org.springframework.beans.factory.support.ManagedList;
15 import org.springframework.beans.factory.support.RootBeanDefinition;
16 import org.springframework.beans.factory.xml.ParserContext;
17 import org.springframework.security.afterinvocation.AfterInvocationProviderManager;
18 import org.springframework.security.util.UrlUtils;
19 import org.springframework.security.vote.AffirmativeBased;
20 import org.springframework.security.vote.AuthenticatedVoter;
21 import org.springframework.security.vote.RoleVoter;
22 import org.springframework.util.StringUtils;
23 import org.w3c.dom.Element;
24
25
26
27
28
29
30
31
32 public abstract class ConfigUtils {
33 private static final Log logger = LogFactory.getLog(ConfigUtils.class);
34
35 static void registerDefaultAccessManagerIfNecessary(ParserContext parserContext) {
36
37 if (!parserContext.getRegistry().containsBeanDefinition(BeanIds.ACCESS_MANAGER)) {
38 ManagedList defaultVoters = new ManagedList(2);
39
40 defaultVoters.add(new RootBeanDefinition(RoleVoter.class));
41 defaultVoters.add(new RootBeanDefinition(AuthenticatedVoter.class));
42
43 BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
44 accessMgrBuilder.addPropertyValue("decisionVoters", defaultVoters);
45 BeanDefinition accessMgr = accessMgrBuilder.getBeanDefinition();
46
47 parserContext.getRegistry().registerBeanDefinition(BeanIds.ACCESS_MANAGER, accessMgr);
48 }
49 }
50
51 public static int countNonEmpty(String[] objects) {
52 int nonNulls = 0;
53
54 for (int i = 0; i < objects.length; i++) {
55 if (StringUtils.hasText(objects[i])) {
56 nonNulls++;
57 }
58 }
59
60 return nonNulls;
61 }
62
63 public static void addVoter(BeanDefinition voter, ParserContext parserContext) {
64 registerDefaultAccessManagerIfNecessary(parserContext);
65
66 BeanDefinition accessMgr = parserContext.getRegistry().getBeanDefinition(BeanIds.ACCESS_MANAGER);
67
68 ManagedList voters = (ManagedList) accessMgr.getPropertyValues().getPropertyValue("decisionVoters").getValue();
69 voters.add(voter);
70
71 accessMgr.getPropertyValues().addPropertyValue("decisionVoters", voters);
72 }
73
74
75
76
77
78
79
80 static void registerProviderManagerIfNecessary(ParserContext parserContext) {
81 if(parserContext.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER)) {
82 return;
83 }
84
85 BeanDefinition authManager = new RootBeanDefinition(NamespaceAuthenticationManager.class);
86 authManager.getPropertyValues().addPropertyValue("providerBeanNames", new ArrayList());
87 parserContext.getRegistry().registerBeanDefinition(BeanIds.AUTHENTICATION_MANAGER, authManager);
88 }
89
90 static void addAuthenticationProvider(ParserContext parserContext, String beanName) {
91 registerProviderManagerIfNecessary(parserContext);
92 BeanDefinition authManager = parserContext.getRegistry().getBeanDefinition(BeanIds.AUTHENTICATION_MANAGER);
93 ((ArrayList) authManager.getPropertyValues().getPropertyValue("providerBeanNames").getValue()).add(beanName);
94 }
95
96 static ManagedList getRegisteredAfterInvocationProviders(ParserContext parserContext) {
97 BeanDefinition manager = registerAfterInvocationProviderManagerIfNecessary(parserContext);
98 return (ManagedList) manager.getPropertyValues().getPropertyValue("providers").getValue();
99 }
100
101 private static BeanDefinition registerAfterInvocationProviderManagerIfNecessary(ParserContext parserContext) {
102 if(parserContext.getRegistry().containsBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER)) {
103 return parserContext.getRegistry().getBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER);
104 }
105
106 BeanDefinition manager = new RootBeanDefinition(AfterInvocationProviderManager.class);
107 manager.getPropertyValues().addPropertyValue("providers", new ManagedList());
108 parserContext.getRegistry().registerBeanDefinition(BeanIds.AFTER_INVOCATION_MANAGER, manager);
109
110 return manager;
111 }
112
113 private static void registerFilterChainPostProcessorIfNecessary(ParserContext pc) {
114 if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_POST_PROCESSOR)) {
115 return;
116 }
117
118 RootBeanDefinition filterChainPostProcessor = new RootBeanDefinition(FilterChainProxyPostProcessor.class);
119 filterChainPostProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
120 pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_POST_PROCESSOR, filterChainPostProcessor);
121 RootBeanDefinition filterList = new RootBeanDefinition(FilterChainList.class);
122 filterList.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
123 pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_LIST, filterList);
124 }
125
126 static void addHttpFilter(ParserContext pc, BeanMetadataElement filter) {
127 registerFilterChainPostProcessorIfNecessary(pc);
128
129 RootBeanDefinition filterList = (RootBeanDefinition) pc.getRegistry().getBeanDefinition(BeanIds.FILTER_LIST);
130
131 ManagedList filters;
132 MutablePropertyValues pvs = filterList.getPropertyValues();
133 if (pvs.contains("filters")) {
134 filters = (ManagedList) pvs.getPropertyValue("filters").getValue();
135 } else {
136 filters = new ManagedList();
137 pvs.addPropertyValue("filters", filters);
138 }
139
140 filters.add(filter);
141 }
142
143
144
145
146
147 public static class FilterChainList {
148 List filters;
149
150 public List getFilters() {
151 return filters;
152 }
153
154 public void setFilters(List filters) {
155 this.filters = filters;
156 }
157 }
158
159
160
161
162
163 static void validateHttpRedirect(String url, ParserContext pc, Object source) {
164 if (UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) {
165 return;
166 }
167 pc.getReaderContext().warning(url + " is not a valid redirect URL (must start with '/' or http(s))", source);
168 }
169
170 static void setSessionControllerOnAuthenticationManager(ParserContext pc, String beanName, Element sourceElt) {
171 registerProviderManagerIfNecessary(pc);
172 BeanDefinition authManager = pc.getRegistry().getBeanDefinition(BeanIds.AUTHENTICATION_MANAGER);
173 PropertyValue pv = authManager.getPropertyValues().getPropertyValue("sessionController");
174
175 if (pv != null && pv.getValue() != null) {
176 pc.getReaderContext().error("A session controller has already been set on the authentication manager. " +
177 "The <concurrent-session-control> element isn't compatible with a custom session controller",
178 pc.extractSource(sourceElt));
179 }
180
181 authManager.getPropertyValues().addPropertyValue("sessionController", new RuntimeBeanReference(beanName));
182 }
183 }