Intermediate checkin of experimental namespace config work.
This commit is contained in:
parent
98f6111d06
commit
627b0b38ad
|
@ -0,0 +1,214 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.security.util.FilterChainProxy;
|
||||
import org.springframework.security.intercept.web.PathBasedFilterInvocationDefinitionMap;
|
||||
import org.springframework.security.intercept.web.FilterSecurityInterceptor;
|
||||
import org.springframework.security.intercept.web.FilterInvocationDefinitionMap;
|
||||
import org.springframework.security.ConfigAttributeEditor;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.ui.ExceptionTranslationFilter;
|
||||
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
|
||||
import org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint;
|
||||
import org.springframework.security.context.HttpSessionContextIntegrationFilter;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Sets up HTTP security: filter stack and protected URLs.
|
||||
*
|
||||
*
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
public static final String DEFAULT_FILTER_CHAIN_PROXY_ID = "_filterChainProxy";
|
||||
|
||||
public static final String DEFAULT_HTTP_SESSION_FILTER_ID = "_httpSessionContextIntegrationFilter";
|
||||
public static final String DEFAULT_LOGOUT_FILTER_ID = "_logoutFilter";
|
||||
public static final String DEFAULT_EXCEPTION_TRANSLATION_FILTER_ID = "_exceptionTranslationFilter";
|
||||
public static final String DEFAULT_FILTER_SECURITY_INTERCEPTOR_ID = "_filterSecurityInterceptor";
|
||||
public static final String DEFAULT_FORM_LOGIN_FILTER_ID = "_formLoginFilter";
|
||||
public static final String DEFAULT_FORM_LOGIN_ENTRY_POINT_ID = "_formLoginEntryPoint";
|
||||
|
||||
public static final String LOGOUT_ELEMENT = "logout";
|
||||
public static final String FORM_LOGIN_ELEMENT = "form-login";
|
||||
|
||||
private static final String PATH_ATTRIBUTE = "path";
|
||||
private static final String FILTERS_ATTRIBUTE = "filters";
|
||||
private static final String ACCESS_CONFIG_ATTRIBUTE = "access";
|
||||
|
||||
private static final String LOGIN_URL_ATTRIBUTE = "loginUrl";
|
||||
|
||||
private static final String FORM_LOGIN_TARGET_URL_ATTRIBUTE = "defaultTargetUrl";
|
||||
private static final String DEFAULT_FORM_LOGIN_TARGET_URL = "/index";
|
||||
|
||||
private static final String FORM_LOGIN_AUTH_FAILURE_URL_ATTRIBUTE = "defaultTargetUrl";
|
||||
// TODO: Change AbstractProcessingFilter to not need a failure URL and just write a failure message
|
||||
// to the response if one isn't set.
|
||||
private static final String DEFAULT_FORM_LOGIN_AUTH_FAILURE_URL = "/loginError";
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
// Create HttpSCIF, FilterInvocationInterceptor, ExceptionTranslationFilter
|
||||
|
||||
// Find other filter beans.
|
||||
|
||||
// Create appropriate bean list for config attributes to create FIDS
|
||||
|
||||
// Add any secure URLs with specific filter chains to FIDS as separate ConfigAttributes
|
||||
|
||||
// Add secure URLS with roles to objectDefinitionSource for FilterSecurityInterceptor
|
||||
|
||||
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
|
||||
|
||||
RootBeanDefinition httpSCIF = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
|
||||
|
||||
//TODO: Set session creation parameters based on session-creation attribute
|
||||
|
||||
BeanDefinitionBuilder filterSecurityInterceptorBuilder
|
||||
= BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);
|
||||
|
||||
|
||||
BeanDefinitionBuilder exceptionTranslationFilterBuilder
|
||||
= BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class);
|
||||
|
||||
// Autowire for entry point (for now)
|
||||
exceptionTranslationFilterBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
|
||||
// TODO: Get path type attribute and determine FilDefInvS class
|
||||
PathBasedFilterInvocationDefinitionMap filterChainInvocationDefSource
|
||||
= new PathBasedFilterInvocationDefinitionMap();
|
||||
|
||||
filterChainProxy.getPropertyValues().addPropertyValue("filterInvocationDefinitionSource",
|
||||
filterChainInvocationDefSource);
|
||||
|
||||
PathBasedFilterInvocationDefinitionMap interceptorFilterInvDefSource
|
||||
= new PathBasedFilterInvocationDefinitionMap();
|
||||
|
||||
filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource);
|
||||
|
||||
// Again pick up auth manager
|
||||
filterSecurityInterceptorBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
|
||||
parseInterceptUrls(DomUtils.getChildElementsByTagName(element, "intercept-url"),
|
||||
filterChainInvocationDefSource, interceptorFilterInvDefSource);
|
||||
// TODO: if empty, set a default set a default /**, omitting login url
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
Element logoutElt = DomUtils.getChildElementByTagName(element, LOGOUT_ELEMENT);
|
||||
|
||||
if (logoutElt != null) {
|
||||
BeanDefinition logoutFilter = new LogoutBeanDefinitionParser().parse(logoutElt, parserContext);
|
||||
}
|
||||
|
||||
Element formLoginElt = DomUtils.getChildElementByTagName(element, FORM_LOGIN_ELEMENT);
|
||||
|
||||
if (formLoginElt != null) {
|
||||
BeanDefinitionBuilder formLoginFilterBuilder =
|
||||
BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProcessingFilter.class);
|
||||
BeanDefinitionBuilder formLoginEntryPointBuilder =
|
||||
BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProcessingFilterEntryPoint.class);
|
||||
|
||||
// Temporary login value
|
||||
formLoginEntryPointBuilder.addPropertyValue("loginFormUrl", "/login");
|
||||
|
||||
|
||||
String loginUrl = formLoginElt.getAttribute(LOGIN_URL_ATTRIBUTE);
|
||||
|
||||
if (StringUtils.hasText(loginUrl)) {
|
||||
formLoginFilterBuilder.addPropertyValue("filterProcessesUrl", loginUrl);
|
||||
}
|
||||
|
||||
String defaultTargetUrl = formLoginElt.getAttribute(FORM_LOGIN_TARGET_URL_ATTRIBUTE);
|
||||
|
||||
if (!StringUtils.hasText(defaultTargetUrl)) {
|
||||
defaultTargetUrl = DEFAULT_FORM_LOGIN_TARGET_URL;
|
||||
}
|
||||
|
||||
formLoginFilterBuilder.addPropertyValue("defaultTargetUrl", defaultTargetUrl);
|
||||
|
||||
String authenticationFailureUrl = formLoginElt.getAttribute(FORM_LOGIN_AUTH_FAILURE_URL_ATTRIBUTE);
|
||||
|
||||
if (!StringUtils.hasText(authenticationFailureUrl)) {
|
||||
authenticationFailureUrl = DEFAULT_FORM_LOGIN_AUTH_FAILURE_URL;
|
||||
}
|
||||
|
||||
formLoginFilterBuilder.addPropertyValue("authenticationFailureUrl", authenticationFailureUrl);
|
||||
// Set autowire to pick up the authentication manager.
|
||||
formLoginFilterBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
|
||||
|
||||
registry.registerBeanDefinition(DEFAULT_FORM_LOGIN_FILTER_ID,
|
||||
formLoginFilterBuilder.getBeanDefinition());
|
||||
registry.registerBeanDefinition(DEFAULT_FORM_LOGIN_ENTRY_POINT_ID,
|
||||
formLoginEntryPointBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
registry.registerBeanDefinition(DEFAULT_FILTER_CHAIN_PROXY_ID, filterChainProxy);
|
||||
registry.registerBeanDefinition(DEFAULT_HTTP_SESSION_FILTER_ID, httpSCIF);
|
||||
registry.registerBeanDefinition(DEFAULT_EXCEPTION_TRANSLATION_FILTER_ID,
|
||||
exceptionTranslationFilterBuilder.getBeanDefinition());
|
||||
registry.registerBeanDefinition(DEFAULT_FILTER_SECURITY_INTERCEPTOR_ID,
|
||||
filterSecurityInterceptorBuilder.getBeanDefinition());
|
||||
|
||||
|
||||
// Register the post processor which will tie up the loose ends in the configuration once the
|
||||
// app context has been created and all beans are available.
|
||||
|
||||
registry.registerBeanDefinition("__httpConfigBeanFactoryPostProcessor",
|
||||
new RootBeanDefinition(HttpSecurityConfigPostProcessor.class));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the intercept-url elements and populates the FilterChainProxy's FilterInvocationDefinitionSource
|
||||
*/
|
||||
private void parseInterceptUrls(List urlElts, FilterInvocationDefinitionMap filterChainInvocationDefSource,
|
||||
FilterInvocationDefinitionMap interceptorFilterInvDefSource) {
|
||||
|
||||
Iterator urlEltsIterator = urlElts.iterator();
|
||||
|
||||
ConfigAttributeEditor attributeEditor = new ConfigAttributeEditor();
|
||||
|
||||
while (urlEltsIterator.hasNext()) {
|
||||
Element urlElt = (Element) urlEltsIterator.next();
|
||||
|
||||
String path = urlElt.getAttribute(PATH_ATTRIBUTE);
|
||||
|
||||
Assert.hasText(path, "path attribute cannot be empty or null");
|
||||
|
||||
String access = urlElt.getAttribute(ACCESS_CONFIG_ATTRIBUTE);
|
||||
|
||||
// Convert the comma-separated list of access attributes to a ConfigAttributeDefinition
|
||||
if (StringUtils.hasText(access)) {
|
||||
attributeEditor.setAsText(access);
|
||||
|
||||
ConfigAttributeDefinition attributeDef = (ConfigAttributeDefinition) attributeEditor.getValue();
|
||||
|
||||
interceptorFilterInvDefSource.addSecureUrl(path, attributeDef);
|
||||
}
|
||||
|
||||
String filters = urlElt.getAttribute(FILTERS_ATTRIBUTE);
|
||||
|
||||
if (StringUtils.hasText(filters)) {
|
||||
attributeEditor.setAsText(filters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.security.util.FilterChainProxy;
|
||||
import org.springframework.security.context.HttpSessionContextIntegrationFilter;
|
||||
import org.springframework.security.AuthenticationManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Responsible for tying up the HTTP security configuration - building ordered filter stack and linking up
|
||||
* with other beans.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor {
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
FilterChainProxy filterChainProxy =
|
||||
(FilterChainProxy) beanFactory.getBean(HttpSecurityBeanDefinitionParser.DEFAULT_FILTER_CHAIN_PROXY_ID);
|
||||
|
||||
HttpSessionContextIntegrationFilter httpSCIF = (HttpSessionContextIntegrationFilter)
|
||||
beanFactory.getBean(HttpSecurityBeanDefinitionParser.DEFAULT_HTTP_SESSION_FILTER_ID);
|
||||
|
||||
AuthenticationManager authManager =
|
||||
(AuthenticationManager) getBeanOfType(AuthenticationManager.class, beanFactory);
|
||||
|
||||
|
||||
//
|
||||
Map filters = beanFactory.getBeansOfType(Filter.class);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void configureFilterChain(ConfigurableListableBeanFactory beanFactory) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Object getBeanOfType(Class clazz, ConfigurableListableBeanFactory beanFactory) {
|
||||
Map beans = beanFactory.getBeansOfType(clazz);
|
||||
|
||||
Assert.isTrue(beans.size() == 1, "Required a single bean of type " + clazz + " but found " + beans.size());
|
||||
|
||||
return beans.values().toArray()[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor;
|
||||
import org.springframework.security.intercept.method.MethodDefinitionMap;
|
||||
import org.springframework.security.ConfigAttributeEditor;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public class InterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {
|
||||
protected BeanDefinition createInterceptorDefinition(Node node) {
|
||||
Element interceptMethodsElt = (Element)node;
|
||||
RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class);
|
||||
|
||||
Element beanNode = (Element)interceptMethodsElt.getParentNode();
|
||||
// Get the class from the parent bean...
|
||||
String targetClassName = beanNode.getAttribute("class");
|
||||
Class targetClass;
|
||||
|
||||
try {
|
||||
targetClass = Thread.currentThread().getContextClassLoader().loadClass(targetClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException("Couldn't load class " + targetClassName, e);
|
||||
}
|
||||
|
||||
// Parse the included methods
|
||||
List methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, "protect");
|
||||
MethodDefinitionMap methodMap = new MethodDefinitionMap();
|
||||
ConfigAttributeEditor attributeEditor = new ConfigAttributeEditor();
|
||||
|
||||
for (Iterator i = methods.iterator(); i.hasNext();) {
|
||||
Element protectmethodElt = (Element) i.next();
|
||||
String accessConfig = protectmethodElt.getAttribute("access");
|
||||
attributeEditor.setAsText(accessConfig);
|
||||
|
||||
methodMap.addSecureMethod(targetClass, protectmethodElt.getAttribute("method"),
|
||||
(ConfigAttributeDefinition) attributeEditor.getValue());
|
||||
}
|
||||
|
||||
interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", methodMap);
|
||||
|
||||
interceptor.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
}
|
|
@ -51,11 +51,8 @@ public class LdapBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
|||
|
||||
// Defaults
|
||||
private static final String DEFAULT_ROOT_SUFFIX = "dc=springframework,dc=org";
|
||||
|
||||
private static final String DEFAULT_PROVIDER_BEAN_ID = "_ldapProvider";
|
||||
|
||||
private static final String DEFAULT_PROVIDER_BEAN_ID = "_ldapAuthenticationProvider";
|
||||
private static final String DEFAULT_DN_PATTERN = "uid={0},ou=people";
|
||||
|
||||
private static final String DEFAULT_GROUP_CONTEXT = "ou=groups";
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.security.ui.logout.LogoutFilter;
|
||||
import org.springframework.security.ui.logout.LogoutHandler;
|
||||
import org.springframework.security.ui.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class LogoutBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
public static final String DEFAULT_LOGOUT_SUCCESS_URL = "/";
|
||||
|
||||
protected Class getBeanClass(Element element) {
|
||||
return LogoutFilter.class;
|
||||
}
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
String logoutUrl = element.getAttribute("logoutUrl");
|
||||
|
||||
if (StringUtils.hasText(logoutUrl)) {
|
||||
builder.addPropertyValue("filterProcessesUrl", logoutUrl);
|
||||
}
|
||||
|
||||
String logoutSuccessUrl = element.getAttribute("logoutSuccessUrl");
|
||||
|
||||
if (!StringUtils.hasText(logoutSuccessUrl)) {
|
||||
logoutSuccessUrl = DEFAULT_LOGOUT_SUCCESS_URL;
|
||||
}
|
||||
|
||||
builder.addConstructorArg(logoutSuccessUrl);
|
||||
builder.addConstructorArg(new LogoutHandler[] {new SecurityContextLogoutHandler()});
|
||||
}
|
||||
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
|
||||
if (StringUtils.hasText(id)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
return HttpSecurityBeanDefinitionParser.DEFAULT_LOGOUT_FILTER_ID;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,9 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
|||
public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("ldap", new LdapBeanDefinitionParser());
|
||||
|
||||
|
||||
registerBeanDefinitionParser("http", new HttpSecurityBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("authentication-provider", new AuthenticationProviderBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("autoconfig", new AutoConfigBeanDefinitionParser());
|
||||
registerBeanDefinitionDecorator("intercept-methods", new InterceptMethodsBeanDefinitionDecorator());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.security.userdetails.memory.InMemoryDaoImpl;
|
||||
import org.springframework.security.userdetails.memory.UserMap;
|
||||
import org.springframework.security.userdetails.User;
|
||||
import org.springframework.security.util.AuthorityUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public class UserServiceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
public static final String DEFAULT_ID = "_userDetailsService";
|
||||
|
||||
protected Class getBeanClass(Element element) {
|
||||
return InMemoryDaoImpl.class;
|
||||
}
|
||||
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
List userElts = DomUtils.getChildElementsByTagName(element, "user");
|
||||
UserMap users = new UserMap();
|
||||
|
||||
for (Iterator i = userElts.iterator(); i.hasNext();) {
|
||||
Element userElt = (Element) i.next();
|
||||
String userName = userElt.getAttribute("name");
|
||||
String password = userElt.getAttribute("password");
|
||||
|
||||
users.addUser(new User(userName, password, true, true, true, true,
|
||||
AuthorityUtils.commaSeparatedStringToAuthorityArray(userElt.getAttribute("authorities"))));
|
||||
}
|
||||
|
||||
builder.addPropertyValue("userMap", users);
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
|
||||
if (StringUtils.hasText(id)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
// TODO: Check for duplicate using default id here.
|
||||
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.springframework.security.util;
|
||||
|
||||
import org.springframework.security.GrantedAuthority;
|
||||
import org.springframework.security.GrantedAuthorityImpl;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AuthorityUtils {
|
||||
|
||||
/**
|
||||
* Creates a array of GrantedAuthority objects from a comma-separated string
|
||||
* representation (e.g. "ROLE_A, ROLE_B, ROLE_C").
|
||||
*
|
||||
* @param authorityString the comma-separated string
|
||||
* @return the authorities created by tokenizing the string
|
||||
*/
|
||||
public static GrantedAuthority[] commaSeparatedStringToAuthorityArray(String authorityString) {
|
||||
String[] authorityStrings = StringUtils.tokenizeToStringArray(authorityString, ",");
|
||||
GrantedAuthority[] authorities = new GrantedAuthority[authorityStrings.length];
|
||||
|
||||
for (int i=0; i < authorityStrings.length; i++) {
|
||||
authorities[i] = new GrantedAuthorityImpl(authorityStrings[i]);
|
||||
}
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,22 +1,184 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://www.springframework.org/schema/security"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
|
||||
<xsd:element name="autoconfig" />
|
||||
|
||||
|
||||
<xsd:element name="ldap">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="url" type="xsd:string" />
|
||||
<xsd:attribute name="ldif" default="classpath:*.ldif"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
<xs:element name="autoconfig">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Provides automatic security configration for a application</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType/>
|
||||
</xs:element>
|
||||
<xs:element name="ldap">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Sets up an ldap authentication provider, optionally with an embedded ldap server</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="ldap.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="ldap.attlist">
|
||||
<xs:attribute name="url" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Specifies the ldap server Url. If omitted, an embedded server will be created </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ldif" default="classpath:*.ldif" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Explicitly specify an ldif file resource to load </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="intercept-methods">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element maxOccurs="unbounded" ref="protect"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="protect">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Defines a protected method and the access control configuration attributes that apply to it</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="protect.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="protect.attlist">
|
||||
<xs:attribute name="method" use="required" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A method name </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="access" use="required" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Access configuration attributes list that applies to the method, e.g. "ROLE_A,ROLE_B"</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="http">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Container element for HTTP security configuration</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element maxOccurs="unbounded" ref="intercept-url"/>
|
||||
<xs:element minOccurs="0" ref="form-login"/>
|
||||
<xs:element minOccurs="0" ref="logout"/>
|
||||
</xs:sequence>
|
||||
<xs:attributeGroup ref="http.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="http.attlist">
|
||||
<xs:attribute name="createSession" default="ifRequired">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls the eagerness with which an HTTP session is created.</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="ifRequired"/>
|
||||
<xs:enumeration value="always"/>
|
||||
<xs:enumeration value="never"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="pathType" default="ant">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Defines the type of path used to define URLs in child elements. </xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="regex"/>
|
||||
<xs:enumeration value="ant"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="lowerCaseComparisons" default="true">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Whether test URLs should be converted to lower case prior to comparing with defined path patterns.</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="true"/>
|
||||
<xs:enumeration value="true"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="intercept-url">
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="intercept-url.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="intercept-url.attlist">
|
||||
<xs:attribute name="path" use="required" type="xs:string"/>
|
||||
<xs:attribute name="access" type="xs:string"/>
|
||||
<xs:attribute name="filters" type="xs:string"/>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="logout">
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="logout.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="logout.attlist">
|
||||
<xs:attribute name="logoutUrl" default="/j_spring_security_logout" type="xs:string"/>
|
||||
<xs:attribute name="logoutSuccessUrl" default="/" type="xs:string"/>
|
||||
<xs:attribute name="invalidateSession" default="true">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="true"/>
|
||||
<xs:enumeration value="false"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="form-login">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Sets up a form login configuration</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="form-login.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="form-login.attlist">
|
||||
<xs:attribute name="loginUrl" default="/j_spring_security_check" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The URL that the form is submitted to</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="authentication-provider">
|
||||
<xs:complexType>
|
||||
<xs:choice>
|
||||
<xs:element ref="user-service"/>
|
||||
<xs:element ref="jdbc-user-service"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="user-service">
|
||||
<xs:complexType>
|
||||
<xs:choice>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" ref="user"/>
|
||||
<xs:element ref="jdbc-user-service"/>
|
||||
</xs:choice>
|
||||
<xs:attributeGroup ref="user-service.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="user-service.attlist">
|
||||
<xs:attribute name="properties" type="xs:string"/>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="user">
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="user.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="user.attlist">
|
||||
<xs:attribute name="name" use="required" type="xs:string"/>
|
||||
<xs:attribute name="password" use="required" type="xs:string"/>
|
||||
<xs:attribute name="authorities" use="required" type="xs:string"/>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="jdbc-user-service">
|
||||
<xs:complexType/>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HttpSecurityBeanDefinitionParserTests {
|
||||
private static ClassPathXmlApplicationContext appContext;
|
||||
|
||||
@BeforeClass
|
||||
public static void loadContext() {
|
||||
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/http-security.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextContainsExpectedBeansAndData() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public class InterceptMethodsBeanDefinitionDecoratorTests {
|
||||
private static ClassPathXmlApplicationContext appContext;
|
||||
|
||||
@BeforeClass
|
||||
public static void loadContext() {
|
||||
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/method-security.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextShouldContainCorrectBeans() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface TestBusinessBean {
|
||||
|
||||
void setInteger(int i);
|
||||
|
||||
int getInteger();
|
||||
|
||||
void setString(String s);
|
||||
|
||||
void doSomething();
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.springframework.security.config;
|
||||
|
||||
/**
|
||||
* @author luke
|
||||
* @version $Id$
|
||||
*/
|
||||
public class TestBusinessBeanImpl implements TestBusinessBean {
|
||||
public void setInteger(int i) {
|
||||
}
|
||||
|
||||
public int getInteger() {
|
||||
return 1314;
|
||||
}
|
||||
|
||||
public void setString(String s) {
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return "A string.";
|
||||
}
|
||||
|
||||
public void doSomething() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
|
||||
|
||||
<security:autoconfig />
|
||||
|
||||
<security:http createSession="ifRequired" pathType="ant" lowerCaseComparisons="true">
|
||||
<security:intercept-url path="/unprotected" filters="none"/>
|
||||
<security:intercept-url path="/somepath" filters="filter1,filter2,filter3" access="ROLE_SPECIAL,ROLE_USER" />
|
||||
<security:intercept-url path="/**" access="ROLE_USER" />
|
||||
|
||||
<!-- Default form login configuration. Will create filter and entry point -->
|
||||
<security:form-login loginUrl="/j_spring_security_check" />
|
||||
|
||||
<!-- Default logout configuration -->
|
||||
<security:logout logoutUrl="/j_spring_security_logout" logoutSuccessUrl="/" invalidateSession="true" />
|
||||
|
||||
</security:http>
|
||||
|
||||
|
||||
<security:authentication-provider>
|
||||
<security:user-service>
|
||||
<security:user name="bob" password="bobspassword" authorities="ROLE_A,ROLE_B" />
|
||||
<security:user name="bill" password="billspassword" authorities="ROLE_A,ROLE_B,AUTH_OTHER" />
|
||||
</security:user-service>
|
||||
</security:authentication-provider>
|
||||
|
||||
</beans>
|
|
@ -10,5 +10,4 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
|
|||
<security:ldap />
|
||||
|
||||
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
|
||||
|
||||
<security:autoconfig />
|
||||
|
||||
<bean id="someBusinessObject" class="org.springframework.security.config.TestBusinessBeanImpl">
|
||||
<!-- This will add a security interceptor to the bean -->
|
||||
<security:intercept-methods>
|
||||
<security:protect method="set*" access="ROLE_ADMIN" />
|
||||
<security:protect method="get*" access="ROLE_ADMIN,ROLE_USER" />
|
||||
<security:protect method="doSomething" access="ROLE_USER" />
|
||||
</security:intercept-methods>
|
||||
</bean>
|
||||
|
||||
<security:authentication-provider>
|
||||
<security:user-service>
|
||||
<security:user name="bob" password="bobspassword" authorities="ROLE_A,ROLE_B" />
|
||||
<security:user name="bill" password="billspassword" authorities="ROLE_A,ROLE_B,AUTH_OTHER" />
|
||||
</security:user-service>
|
||||
</security:authentication-provider>
|
||||
|
||||
</beans>
|
Loading…
Reference in New Issue