SEC-1312: Add detection of 2.0 schemas. Added check to SecurityNamespaceHandler and reinstated old schemas.
This commit is contained in:
parent
ab48d72cc2
commit
d4e4a09801
|
@ -1,6 +1,14 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.NamespaceHandler;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.config.authentication.AuthenticationManagerBeanDefinitionParser;
|
||||
import org.springframework.security.config.authentication.AuthenticationProviderBeanDefinitionParser;
|
||||
import org.springframework.security.config.authentication.JdbcUserServiceBeanDefinitionParser;
|
||||
|
@ -14,6 +22,8 @@ import org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionPar
|
|||
import org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParser;
|
||||
import org.springframework.security.config.method.InterceptMethodsBeanDefinitionDecorator;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Registers the bean definition parsers for the "security" namespace (http://www.springframework.org/schema/security).
|
||||
|
@ -23,28 +33,106 @@ import org.springframework.util.ClassUtils;
|
|||
* @since 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
||||
public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
private final Map<String, BeanDefinitionParser> parsers = new HashMap<String, BeanDefinitionParser>();
|
||||
private final BeanDefinitionDecorator interceptMethodsBDD = new InterceptMethodsBeanDefinitionDecorator();
|
||||
private BeanDefinitionDecorator filterChainMapBDD;
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext pc) {
|
||||
if (!namespaceMatchesVersion(element)) {
|
||||
pc.getReaderContext().fatal("You cannot use a spring-security-2.0.xsd schema with Spring Security 3.0." +
|
||||
" Please update your schema declarations to the 3.0 schema.", element);
|
||||
}
|
||||
String name = pc.getDelegate().getLocalName(element);
|
||||
BeanDefinitionParser parser = parsers.get(name);
|
||||
|
||||
if (parser == null) {
|
||||
if (Elements.HTTP.equals(name) || Elements.FILTER_SECURITY_METADATA_SOURCE.equals(name)) {
|
||||
reportMissingWebClasses(name, pc, element);
|
||||
} else {
|
||||
reportUnsupportedNodeType(name, pc, element);
|
||||
}
|
||||
}
|
||||
|
||||
return parser.parse(element, pc);
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext pc) {
|
||||
BeanDefinitionDecorator decorator = null;
|
||||
String name = pc.getDelegate().getLocalName(node);
|
||||
|
||||
// We only handle elements
|
||||
if (node instanceof Element) {
|
||||
if (Elements.INTERCEPT_METHODS.equals(name)) {
|
||||
return interceptMethodsBDD.decorate(node, definition, pc);
|
||||
}
|
||||
|
||||
if (Elements.FILTER_CHAIN_MAP.equals(name)) {
|
||||
if (filterChainMapBDD == null) {
|
||||
reportMissingWebClasses(name, pc, node);
|
||||
}
|
||||
return filterChainMapBDD.decorate(node, definition, pc);
|
||||
}
|
||||
}
|
||||
|
||||
if (decorator == null) {
|
||||
reportUnsupportedNodeType(name, pc, node);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void reportUnsupportedNodeType(String name, ParserContext pc, Node node) {
|
||||
pc.getReaderContext().fatal("Security namespace does not support decoration of " +
|
||||
(node instanceof Element ? "element" : "attribute") + " [" + name + "]", node);
|
||||
}
|
||||
|
||||
private void reportMissingWebClasses(String nodeName, ParserContext pc, Node node) {
|
||||
pc.getReaderContext().fatal("spring-security-web classes are not available. " +
|
||||
"You need these to use <" + Elements.FILTER_CHAIN_MAP + ">", node);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void init() {
|
||||
// Parsers
|
||||
registerBeanDefinitionParser(Elements.LDAP_PROVIDER, new LdapProviderBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.LDAP_SERVER, new LdapServerBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.LDAP_USER_SERVICE, new LdapUserServiceBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.USER_SERVICE, new UserServiceBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.JDBC_USER_SERVICE, new JdbcUserServiceBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.AUTHENTICATION_PROVIDER, new AuthenticationProviderBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
|
||||
registerBeanDefinitionParser(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
|
||||
registerBeanDefinitionDecorator(Elements.INTERCEPT_METHODS, new InterceptMethodsBeanDefinitionDecorator());
|
||||
parsers.put(Elements.LDAP_PROVIDER, new LdapProviderBeanDefinitionParser());
|
||||
parsers.put(Elements.LDAP_SERVER, new LdapServerBeanDefinitionParser());
|
||||
parsers.put(Elements.LDAP_USER_SERVICE, new LdapUserServiceBeanDefinitionParser());
|
||||
parsers.put(Elements.USER_SERVICE, new UserServiceBeanDefinitionParser());
|
||||
parsers.put(Elements.JDBC_USER_SERVICE, new JdbcUserServiceBeanDefinitionParser());
|
||||
parsers.put(Elements.AUTHENTICATION_PROVIDER, new AuthenticationProviderBeanDefinitionParser());
|
||||
parsers.put(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
|
||||
parsers.put(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
|
||||
// registerBeanDefinitionDecorator(Elements.INTERCEPT_METHODS, new InterceptMethodsBeanDefinitionDecorator());
|
||||
|
||||
// Web-namespace stuff
|
||||
if (ClassUtils.isPresent("org.springframework.security.web.FilterChainProxy", ClassUtils.getDefaultClassLoader())) {
|
||||
registerBeanDefinitionParser(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
|
||||
registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator());
|
||||
registerBeanDefinitionParser(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
registerBeanDefinitionParser(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
|
||||
parsers.put(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
parsers.put(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
filterChainMapBDD = new FilterChainMapBeanDefinitionDecorator();
|
||||
//registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the schema location declared in the source file being parsed matches the Spring Batch version.
|
||||
* The old 2.0 schema is not compatible with the new 3.0 parser, so it is an error to explicitly use
|
||||
* 3.0. It might be an error to declare spring-security.xsd as an alias, but you are only going to find that out
|
||||
* when one of the sub parsers breaks.
|
||||
*
|
||||
* @param element the element that is to be parsed next
|
||||
* @return true if we find a schema declaration that matches
|
||||
*/
|
||||
private boolean namespaceMatchesVersion(Element element) {
|
||||
return matchesVersionInternal(element) && matchesVersionInternal(element.getOwnerDocument().getDocumentElement());
|
||||
}
|
||||
|
||||
private boolean matchesVersionInternal(Element element) {
|
||||
String schemaLocation = element.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
|
||||
return schemaLocation.matches("(?m).*spring-security-3.0.xsd.*")
|
||||
|| schemaLocation.matches("(?m).*spring-security.xsd.*")
|
||||
|| !schemaLocation.matches("(?m).*spring-security.*");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-3.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-3.0.xsd=org/springframework/security/config/spring-security-3.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.xsd=org/springframework/security/config/spring-security-2.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.1.xsd=org/springframework/security/config/spring-security-2.0.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.2.xsd=org/springframework/security/config/spring-security-2.0.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.4.xsd=org/springframework/security/config/spring-security-2.0.4.xsd
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SecurityNamespacehandlerTests {
|
||||
|
||||
@Test
|
||||
public void pre3SchemaAreNotSupported() throws Exception {
|
||||
try {
|
||||
new InMemoryXmlApplicationContext(
|
||||
"<user-service id='us'>" +
|
||||
" <user name='bob' password='bobspassword' authorities='ROLE_A' />" +
|
||||
"</user-service>", "2.0.4", null
|
||||
);
|
||||
fail("Expected BeanDefinitionParsingException");
|
||||
} catch (BeanDefinitionParsingException expected) {
|
||||
assertTrue(expected.getMessage().contains("You cannot use a spring-security-2.0.xsd schema"));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue