Intermediate checkin of experimental namespace config work.

This commit is contained in:
Luke Taylor 2007-10-13 16:24:24 +00:00
parent 98f6111d06
commit 627b0b38ad
16 changed files with 804 additions and 26 deletions

View File

@ -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);
}
}
}
}

View File

@ -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];
}
}

View File

@ -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;
}
}

View File

@ -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";

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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() {
}
}

View File

@ -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() {
}
}

View File

@ -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();
}

View File

@ -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() {
}
}

View File

@ -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>

View File

@ -10,5 +10,4 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
<security:ldap />
</beans>

View File

@ -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>