23 changed files with 455 additions and 395 deletions
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
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.AbstractBeanDefinition; |
||||
import org.springframework.beans.factory.BeanDefinitionStoreException; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
*/ |
||||
public class AbstractUserDetailsServiceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { |
||||
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { |
||||
String id = super.resolveId(element, definition, parserContext); |
||||
|
||||
if (StringUtils.hasText(id)) { |
||||
return id; |
||||
} |
||||
|
||||
if (parserContext.getRegistry().containsBeanDefinition(BeanIds.USER_DETAILS_SERVICE)) { |
||||
throw new SecurityConfigurationException("No id supplied in <" + element.getNodeName() + "> and another " + |
||||
"bean is already registered as " + BeanIds.USER_DETAILS_SERVICE); |
||||
} |
||||
|
||||
return BeanIds.USER_DETAILS_SERVICE; |
||||
} |
||||
} |
||||
@ -1,18 +1,67 @@
@@ -1,18 +1,67 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.security.providers.dao.DaoAuthenticationProvider; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.config.RuntimeBeanReference; |
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.util.xml.DomUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* Wraps a UserDetailsService bean with a DaoAuthenticationProvider and registers the latter with the |
||||
* ProviderManager. |
||||
* |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
*/ |
||||
class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser { |
||||
private static String ATT_REF = "ref"; |
||||
static final String ATT_DATA_SOURCE = "data-source"; |
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) { |
||||
// TODO: Proper implementation
|
||||
RootBeanDefinition authProvider = new RootBeanDefinition(DaoAuthenticationProvider.class); |
||||
|
||||
Element passwordEncoderElt = DomUtils.getChildElementByTagName(element, Elements.PASSWORD_ENCODER); |
||||
|
||||
if (passwordEncoderElt != null) { |
||||
//TODO: Parse password encoder object and add to dao provider
|
||||
} |
||||
|
||||
ConfigUtils.getRegisteredProviders(parserContext).add(authProvider); |
||||
|
||||
String ref = element.getAttribute(ATT_REF); |
||||
Element userServiceElt = DomUtils.getChildElementByTagName(element, Elements.USER_SERVICE); |
||||
Element jdbcUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE); |
||||
|
||||
if (StringUtils.hasText(ref)) { |
||||
if (userServiceElt != null || jdbcUserServiceElt != null) { |
||||
throw new SecurityConfigurationException("The ref attribute cannot be used in combination with child" + |
||||
"elements '" + Elements.USER_SERVICE + "' or '" + Elements.JDBC_USER_SERVICE + "'"); |
||||
} |
||||
|
||||
authProvider.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(ref)); |
||||
|
||||
return null; |
||||
} |
||||
|
||||
// Use the child elements to create the UserDetailsService
|
||||
BeanDefinition userDetailsService; |
||||
|
||||
if (userServiceElt != null) { |
||||
userDetailsService = new UserServiceBeanDefinitionParser().parse(userServiceElt, parserContext); |
||||
} else if (jdbcUserServiceElt != null) { |
||||
userDetailsService = new UserServiceBeanDefinitionParser().parse(userServiceElt, parserContext); |
||||
} else { |
||||
throw new SecurityConfigurationException(Elements.AUTHENTICATION_PROVIDER |
||||
+ " requireds a UserDetailsService" ); |
||||
} |
||||
|
||||
authProvider.getPropertyValues().addPropertyValue("userDetailsService", userDetailsService); |
||||
|
||||
return null; |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.security.userdetails.jdbc.JdbcUserDetailsManager; |
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
||||
|
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
*/ |
||||
public class JdbcUserServiceBeanDefinitionParser extends AbstractUserDetailsServiceBeanDefinitionParser { |
||||
static final String ATT_DATA_SOURCE = "data-source"; |
||||
|
||||
protected Class getBeanClass(Element element) { |
||||
return JdbcUserDetailsManager.class; |
||||
} |
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) { |
||||
// TODO: Set authenticationManager property
|
||||
String dataSource = element.getAttribute(ATT_DATA_SOURCE); |
||||
// An explicit dataSource was specified, so use it
|
||||
if (dataSource != null) { |
||||
builder.addPropertyReference("dataSource", dataSource); |
||||
} else { |
||||
// TODO: Have some sensible fallback if dataSource not specified, eg autowire
|
||||
throw new SecurityConfigurationException(ATT_DATA_SOURCE + " is required for " |
||||
+ Elements.JDBC_USER_SERVICE ); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.security.providers.encoding.Md4PasswordEncoder; |
||||
import org.springframework.security.providers.encoding.Md5PasswordEncoder; |
||||
import org.springframework.security.providers.encoding.ShaPasswordEncoder; |
||||
import org.springframework.security.providers.encoding.BaseDigestPasswordEncoder; |
||||
import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder; |
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.util.xml.DomUtils; |
||||
|
||||
import org.w3c.dom.Element; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import java.util.Map; |
||||
import java.util.HashMap; |
||||
|
||||
/** |
||||
* Stateful parser for the <password-encoder> element. |
||||
* |
||||
* Will produce a PasswordEncoder and (optionally) a SaltSource. |
||||
* |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
*/ |
||||
public class PasswordEncoderParser { |
||||
static final String ATT_REF = "ref"; |
||||
static final String ATT_HASH = "hash"; |
||||
static final String ATT_BASE_64 = "base64"; |
||||
static final String OPT_HASH_SHA = "sha"; |
||||
static final String OPT_HASH_MD4 = "md4"; |
||||
static final String OPT_HASH_MD5 = "md5"; |
||||
static final String OPT_HASH_LDAP_SHA = "{sha}"; |
||||
|
||||
static final Map ENCODER_CLASSES; |
||||
|
||||
static { |
||||
ENCODER_CLASSES = new HashMap(); |
||||
ENCODER_CLASSES.put(OPT_HASH_SHA, ShaPasswordEncoder.class); |
||||
ENCODER_CLASSES.put(OPT_HASH_MD4, Md4PasswordEncoder.class); |
||||
ENCODER_CLASSES.put(OPT_HASH_MD5, Md5PasswordEncoder.class); |
||||
ENCODER_CLASSES.put(OPT_HASH_LDAP_SHA, LdapShaPasswordEncoder.class); |
||||
} |
||||
|
||||
private Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private BeanDefinition passwordEncoder; |
||||
private BeanDefinition saltSource; |
||||
|
||||
|
||||
public PasswordEncoderParser(Element element, ParserContext parserContext) { |
||||
parse(element, parserContext); |
||||
} |
||||
|
||||
private void parse(Element element, ParserContext parserContext) { |
||||
String hash = element.getAttribute(ATT_HASH); |
||||
boolean useBase64 = StringUtils.hasText(element.getAttribute(ATT_BASE_64)); |
||||
|
||||
Class beanClass = (Class) ENCODER_CLASSES.get(hash); |
||||
passwordEncoder = new RootBeanDefinition(beanClass); |
||||
|
||||
if (useBase64) { |
||||
if (beanClass.isAssignableFrom(BaseDigestPasswordEncoder.class)) { |
||||
passwordEncoder.getPropertyValues().addPropertyValue("encodeHashAsBase64", "true"); |
||||
} else { |
||||
logger.warn(ATT_BASE_64 + " isn't compatible with " + OPT_HASH_LDAP_SHA + " and will be ignored"); |
||||
} |
||||
} |
||||
|
||||
Element saltSourceElt = DomUtils.getChildElementByTagName(element, Elements.SALT_SOURCE); |
||||
|
||||
if (saltSourceElt != null) { |
||||
saltSource = new SaltSourceBeanDefinitionParser().parse(saltSourceElt, parserContext); |
||||
} |
||||
} |
||||
|
||||
public BeanDefinition getPasswordEncoder() { |
||||
return passwordEncoder; |
||||
} |
||||
|
||||
public BeanDefinition getSaltSource() { |
||||
return saltSource; |
||||
} |
||||
} |
||||
@ -1,119 +0,0 @@
@@ -1,119 +0,0 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.security.providers.dao.DaoAuthenticationProvider; |
||||
import org.springframework.security.providers.encoding.Md4PasswordEncoder; |
||||
import org.springframework.security.providers.encoding.Md5PasswordEncoder; |
||||
import org.springframework.security.providers.encoding.PasswordEncoder; |
||||
import org.springframework.security.providers.encoding.PlaintextPasswordEncoder; |
||||
import org.springframework.security.providers.encoding.ShaPasswordEncoder; |
||||
import org.springframework.security.userdetails.jdbc.JdbcUserDetailsManager; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.util.xml.DomUtils; |
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* Processes the top-level "repository" element. |
||||
* |
||||
* <p>A "repository" element is used to indicate a UserDetailsService or equivalent. |
||||
* |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
class RepositoryBeanDefinitionParser implements BeanDefinitionParser { |
||||
|
||||
static final String ATT_DATA_SOURCE = "data-source"; |
||||
static final String ATT_REF = "ref"; |
||||
|
||||
static final String ATT_CREATE_PROVIDER = "create-provider"; |
||||
static final String DEF_CREATE_PROVIDER = "true"; |
||||
|
||||
static final String ATT_HASH = "hash"; |
||||
static final String DEF_HASH_PLAINTEXT = "plaintext"; |
||||
static final String OPT_HASH_SHA_HEX = "sha-hex"; |
||||
static final String OPT_HASH_SHA_BASE64 = "sha-base64"; |
||||
static final String OPT_HASH_MD4_HEX = "md4-hex"; |
||||
static final String OPT_HASH_MD4_BASE64 = "md4-base64"; |
||||
static final String OPT_HASH_MD5_HEX = "md5-hex"; |
||||
static final String OPT_HASH_MD5_BASE64 = "md5-base64"; |
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) { |
||||
boolean createProvider = true; |
||||
String createProviderAtt = element.getAttribute(ATT_CREATE_PROVIDER); |
||||
if (StringUtils.hasText(createProviderAtt) && "false".equals(createProviderAtt)) { |
||||
createProvider = false; |
||||
} |
||||
|
||||
if (createProvider) { |
||||
ConfigUtils.registerProviderManagerIfNecessary(parserContext); |
||||
} |
||||
|
||||
Element userServiceElt = DomUtils.getChildElementByTagName(element, Elements.USER_SERVICE); |
||||
Element jdbcUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE); |
||||
Element customUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.CUSTOM_USER_SERVICE); |
||||
|
||||
if (userServiceElt != null) { |
||||
BeanDefinition userDetailsService = new UserServiceBeanDefinitionParser().parse(userServiceElt, parserContext); |
||||
createDaoAuthenticationProviderIfRequired(createProvider, userServiceElt.getAttribute(ATT_HASH), userDetailsService, parserContext); |
||||
} |
||||
|
||||
if (jdbcUserServiceElt != null) { |
||||
// TODO: Set authenticationManager property
|
||||
// TODO: Have some sensible fallback if dataSource not specified, eg autowire
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(JdbcUserDetailsManager.class); |
||||
String dataSource = jdbcUserServiceElt.getAttribute(ATT_DATA_SOURCE); |
||||
// An explicit dataSource was specified, so use it
|
||||
builder.addPropertyReference("dataSource", dataSource); |
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.JDBC_USER_DETAILS_MANAGER, builder.getBeanDefinition()); |
||||
createDaoAuthenticationProviderIfRequired(createProvider, jdbcUserServiceElt.getAttribute(ATT_HASH), builder.getBeanDefinition(), parserContext); |
||||
} |
||||
|
||||
if (customUserServiceElt != null) { |
||||
String ref = customUserServiceElt.getAttribute(ATT_REF); |
||||
BeanDefinition userDetailsService = parserContext.getRegistry().getBeanDefinition(ref); |
||||
createDaoAuthenticationProviderIfRequired(createProvider, customUserServiceElt.getAttribute(ATT_HASH), userDetailsService, parserContext); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
private void createDaoAuthenticationProviderIfRequired(boolean createProvider, String hash, BeanDefinition userDetailsService, ParserContext parserContext) { |
||||
if (createProvider) { |
||||
if (!StringUtils.hasText(hash)) { |
||||
hash = DEF_HASH_PLAINTEXT; |
||||
} |
||||
RootBeanDefinition authProvider = new RootBeanDefinition(DaoAuthenticationProvider.class); |
||||
authProvider.getPropertyValues().addPropertyValue("userDetailsService", userDetailsService); |
||||
|
||||
PasswordEncoder pwdEnc = null; |
||||
if (OPT_HASH_MD4_HEX.equals(hash)) { |
||||
pwdEnc = new Md4PasswordEncoder(); |
||||
((Md4PasswordEncoder)pwdEnc).setEncodeHashAsBase64(false); |
||||
} else if (OPT_HASH_MD4_BASE64.equals(hash)) { |
||||
pwdEnc = new Md4PasswordEncoder(); |
||||
((Md4PasswordEncoder)pwdEnc).setEncodeHashAsBase64(true); |
||||
} else if (OPT_HASH_MD5_HEX.equals(hash)) { |
||||
pwdEnc = new Md5PasswordEncoder(); |
||||
((Md5PasswordEncoder)pwdEnc).setEncodeHashAsBase64(false); |
||||
} else if (OPT_HASH_MD5_BASE64.equals(hash)) { |
||||
pwdEnc = new Md5PasswordEncoder(); |
||||
((Md5PasswordEncoder)pwdEnc).setEncodeHashAsBase64(true); |
||||
} else if (OPT_HASH_SHA_HEX.equals(hash)) { |
||||
pwdEnc = new ShaPasswordEncoder(); |
||||
((ShaPasswordEncoder)pwdEnc).setEncodeHashAsBase64(false); |
||||
} else if (OPT_HASH_SHA_BASE64.equals(hash)) { |
||||
pwdEnc = new ShaPasswordEncoder(); |
||||
((ShaPasswordEncoder)pwdEnc).setEncodeHashAsBase64(true); |
||||
} else { |
||||
pwdEnc = new PlaintextPasswordEncoder(); |
||||
} |
||||
authProvider.getPropertyValues().addPropertyValue("passwordEncoder", pwdEnc); |
||||
|
||||
ConfigUtils.getRegisteredProviders(parserContext).add(authProvider); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.security.providers.dao.salt.ReflectionSaltSource; |
||||
import org.springframework.security.providers.dao.salt.SystemWideSaltSource; |
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* @author Luke Taylor |
||||
* @version $Id$ |
||||
*/ |
||||
public class SaltSourceBeanDefinitionParser implements BeanDefinitionParser { |
||||
static final String ATT_USER_PROPERTY = "user-property"; |
||||
static final String ATT_SYSTEM_WIDE = "system-wide"; |
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) { |
||||
BeanDefinition saltSource; |
||||
String userProperty = element.getAttribute(ATT_USER_PROPERTY); |
||||
|
||||
if (StringUtils.hasText(userProperty)) { |
||||
saltSource = new RootBeanDefinition(ReflectionSaltSource.class); |
||||
saltSource.getPropertyValues().addPropertyValue("userPropertyToUse", userProperty); |
||||
|
||||
return saltSource; |
||||
} |
||||
|
||||
String systemWideSalt = element.getAttribute(ATT_SYSTEM_WIDE); |
||||
|
||||
if (StringUtils.hasText(systemWideSalt)) { |
||||
saltSource = new RootBeanDefinition(SystemWideSaltSource.class); |
||||
saltSource.getPropertyValues().addPropertyValue("systemWideSalt", systemWideSalt); |
||||
|
||||
return saltSource; |
||||
} |
||||
|
||||
throw new SecurityConfigurationException(Elements.SALT_SOURCE + " requires an attribute"); |
||||
} |
||||
} |
||||
@ -1,39 +0,0 @@
@@ -1,39 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.security.config; |
||||
|
||||
import org.springframework.dao.DataAccessException; |
||||
import org.springframework.security.GrantedAuthority; |
||||
import org.springframework.security.GrantedAuthorityImpl; |
||||
import org.springframework.security.userdetails.User; |
||||
import org.springframework.security.userdetails.UserDetails; |
||||
import org.springframework.security.userdetails.UserDetailsService; |
||||
import org.springframework.security.userdetails.UsernameNotFoundException; |
||||
|
||||
|
||||
/** |
||||
* @author Ben Alex |
||||
* @version $Id: DataSourcePopulator.java 2291 2007-12-03 02:56:52Z benalex $ |
||||
*/ |
||||
public class CustomUserDetailsService implements UserDetailsService { |
||||
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { |
||||
if ("rod".equals(username)) { |
||||
return new User("rod", "koala", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO")}); |
||||
} |
||||
throw new UsernameNotFoundException("unsupported by stub"); |
||||
} |
||||
|
||||
} |
||||
@ -1,48 +0,0 @@
@@ -1,48 +0,0 @@
|
||||
package org.springframework.security.config; |
||||
|
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.AfterClass; |
||||
import org.junit.BeforeClass; |
||||
import org.junit.Test; |
||||
import org.springframework.context.support.ClassPathXmlApplicationContext; |
||||
import org.springframework.security.providers.ProviderManager; |
||||
import org.springframework.security.providers.dao.DaoAuthenticationProvider; |
||||
|
||||
/** |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public class CustomUserDetailsTests { |
||||
private static ClassPathXmlApplicationContext appContext; |
||||
|
||||
@BeforeClass |
||||
public static void loadContext() { |
||||
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/custom-user-details.xml"); |
||||
} |
||||
|
||||
@AfterClass |
||||
public static void closeAppContext() { |
||||
if (appContext != null) { |
||||
appContext.close(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testUsersFound() { |
||||
CustomUserDetailsService mgr = (CustomUserDetailsService) appContext.getBean("myDetails"); |
||||
assertTrue(mgr.loadUserByUsername("rod") != null); |
||||
} |
||||
|
||||
@Test |
||||
public void testProviderManagerSetup() { |
||||
ProviderManager manager = (ProviderManager) appContext.getBean(BeanIds.AUTHENTICATION_MANAGER); |
||||
List providers = manager.getProviders(); |
||||
assertTrue(providers.size() == 1); |
||||
assertTrue(providers.iterator().next() instanceof DaoAuthenticationProvider); |
||||
DaoAuthenticationProvider provider = (DaoAuthenticationProvider) providers.iterator().next(); |
||||
assertTrue(provider.getUserDetailsService() instanceof CustomUserDetailsService); |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security" |
||||
xmlns:beans="http://www.springframework.org/schema/beans" |
||||
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"> |
||||
|
||||
<beans:bean id="myDetails" class="org.springframework.security.config.CustomUserDetailsService"/> |
||||
|
||||
<repository> |
||||
<custom-user-service ref="myDetails"/> |
||||
</repository> |
||||
|
||||
</beans:beans> |
||||
Loading…
Reference in new issue