1 package org.springframework.security.oauth.config;
2
3 import java.lang.reflect.Method;
4 import java.util.Collections;
5 import java.util.List;
6
7 import org.springframework.beans.BeanMetadataElement;
8 import org.springframework.beans.factory.config.BeanDefinition;
9 import org.springframework.beans.factory.config.BeanReference;
10 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
11 import org.springframework.beans.factory.support.ManagedMap;
12 import org.springframework.beans.factory.xml.ParserContext;
13 import org.springframework.security.access.SecurityConfig;
14 import org.springframework.security.config.BeanIds;
15 import org.springframework.security.config.http.MatcherType;
16 import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
17 import org.springframework.util.ReflectionUtils;
18 import org.springframework.util.StringUtils;
19 import org.springframework.util.xml.DomUtils;
20 import org.w3c.dom.Element;
21
22
23
24
25
26
27
28 public class ConfigUtils {
29 private static final Method createMatcherMethod3x = ReflectionUtils.findMethod(
30 MatcherType.class, "createMatcher", String.class, String.class);
31 private static final Method createMatcherMethod4x = ReflectionUtils.findMethod(
32 MatcherType.class, "createMatcher", ParserContext.class, String.class, String.class);
33
34 private ConfigUtils() {
35 }
36
37 public static BeanDefinition createSecurityMetadataSource(Element element, ParserContext pc) {
38 List<Element> filterPatterns = DomUtils.getChildElementsByTagName(element, "url");
39
40 if (filterPatterns.isEmpty()) {
41 return null;
42 }
43
44 String patternType = element.getAttribute("path-type");
45 if (!StringUtils.hasText(patternType)) {
46 patternType = "ant";
47 }
48
49 MatcherType matcherType = MatcherType.valueOf(patternType);
50
51 ManagedMap<BeanDefinition, BeanDefinition> invocationDefinitionMap = new ManagedMap<BeanDefinition, BeanDefinition>();
52
53 for (Element filterPattern : filterPatterns) {
54 String path = filterPattern.getAttribute("pattern");
55 if (!StringUtils.hasText(path)) {
56 pc.getReaderContext().error("pattern attribute cannot be empty or null", filterPattern);
57 }
58
59 String method = filterPattern.getAttribute("httpMethod");
60 if (!StringUtils.hasText(method)) {
61 method = null;
62 }
63
64 String access = filterPattern.getAttribute("resources");
65
66 if (StringUtils.hasText(access)) {
67 BeanDefinition matcher;
68 if (createMatcherMethod4x != null) {
69 matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod4x, matcherType, pc, path, method);
70 } else {
71 matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod3x, matcherType, path, method);
72 }
73
74 if (access.equals("none")) {
75 invocationDefinitionMap.put(matcher, BeanDefinitionBuilder.rootBeanDefinition(Collections.class).setFactoryMethod("emptyList").getBeanDefinition());
76 }
77 else {
78 BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
79 attributeBuilder.addConstructorArgValue(access);
80 attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString");
81
82 if (invocationDefinitionMap.containsKey(matcher)) {
83 pc.getReaderContext().warning("Duplicate URL defined: " + path
84 + ". The original attribute values will be overwritten", pc.extractSource(filterPattern));
85 }
86
87 invocationDefinitionMap.put(matcher, attributeBuilder.getBeanDefinition());
88 }
89 }
90 }
91
92 BeanDefinitionBuilder fidsBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);
93 fidsBuilder.addConstructorArgValue(invocationDefinitionMap);
94 fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(element));
95
96 return fidsBuilder.getBeanDefinition();
97 }
98
99 @SuppressWarnings({"unchecked"})
100 public static List<BeanMetadataElement> findFilterChain(ParserContext parserContext, String explicitRef) {
101 String filterChainRef = explicitRef;
102 if (!StringUtils.hasText(filterChainRef)) {
103 filterChainRef = findDefaultFilterChainBeanId(parserContext);
104 }
105 return (List<BeanMetadataElement>)
106 parserContext.getRegistry().getBeanDefinition(filterChainRef).getConstructorArgumentValues().getArgumentValue(1,List.class).getValue();
107 }
108
109 @SuppressWarnings({"unchecked"})
110 protected static String findDefaultFilterChainBeanId(ParserContext parserContext) {
111 BeanDefinition filterChainList = parserContext.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAINS);
112
113 List<BeanReference> filterChains = (List<BeanReference>)
114 filterChainList.getPropertyValues().getPropertyValue("sourceList").getValue();
115
116 return filterChains.get(filterChains.size() - 1).getBeanName();
117 }
118
119 }