diff --git a/config/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java index 66e9c0957a..18375a537a 100644 --- a/config/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java @@ -64,7 +64,7 @@ public class AnonymousBeanDefinitionParser implements BeanDefinitionParser { provider.getPropertyValues().addPropertyValue(ATT_KEY, key); parserContext.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER, provider); - ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER); + ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER, null); return filter; } diff --git a/config/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java index f2c4a60467..a119fe3f2c 100644 --- a/config/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java @@ -94,7 +94,7 @@ class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser parserContext.getRegistry().registerBeanDefinition(name , cacheResolver); parserContext.registerComponent(new BeanComponentDefinition(cacheResolver, name)); - ConfigUtils.addAuthenticationProvider(parserContext, id); + ConfigUtils.addAuthenticationProvider(parserContext, id, element); return null; } diff --git a/config/src/main/java/org/springframework/security/config/ConfigUtils.java b/config/src/main/java/org/springframework/security/config/ConfigUtils.java index 796bcb5e40..17c333d9fa 100644 --- a/config/src/main/java/org/springframework/security/config/ConfigUtils.java +++ b/config/src/main/java/org/springframework/security/config/ConfigUtils.java @@ -84,8 +84,8 @@ abstract class ConfigUtils { } @SuppressWarnings("unchecked") - static void addAuthenticationProvider(ParserContext parserContext, String beanName) { - registerProviderManagerIfNecessary(parserContext, null); + static void addAuthenticationProvider(ParserContext parserContext, String beanName, Element element) { + registerProviderManagerIfNecessary(parserContext, element); BeanDefinition authManager = parserContext.getRegistry().getBeanDefinition(BeanIds.AUTHENTICATION_MANAGER); ((ArrayList) authManager.getPropertyValues().getPropertyValue("providerBeanNames").getValue()).add(beanName); } diff --git a/config/src/main/java/org/springframework/security/config/CustomAuthenticationProviderBeanDefinitionDecorator.java b/config/src/main/java/org/springframework/security/config/CustomAuthenticationProviderBeanDefinitionDecorator.java index caa7a38c3a..dc0918b988 100644 --- a/config/src/main/java/org/springframework/security/config/CustomAuthenticationProviderBeanDefinitionDecorator.java +++ b/config/src/main/java/org/springframework/security/config/CustomAuthenticationProviderBeanDefinitionDecorator.java @@ -3,6 +3,7 @@ package org.springframework.security.config; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.xml.BeanDefinitionDecorator; import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; import org.w3c.dom.Node; /** @@ -14,7 +15,7 @@ import org.w3c.dom.Node; */ public class CustomAuthenticationProviderBeanDefinitionDecorator implements BeanDefinitionDecorator { public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) { - ConfigUtils.addAuthenticationProvider(parserContext, holder.getBeanName()); + ConfigUtils.addAuthenticationProvider(parserContext, holder.getBeanName(), (Element) node); return holder; } diff --git a/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java index 107adfa545..4f9fdaf0f9 100644 --- a/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java @@ -2,6 +2,8 @@ package org.springframework.security.config; import static org.springframework.security.config.FilterChainOrder.*; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; @@ -30,6 +32,7 @@ import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.access.vote.AuthenticatedVoter; import org.springframework.security.access.vote.RoleVoter; +import org.springframework.security.authentication.AnonymousAuthenticationProvider; import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.access.AccessDeniedHandlerImpl; import org.springframework.security.web.access.ExceptionTranslationFilter; @@ -43,6 +46,7 @@ import org.springframework.security.web.access.expression.WebExpressionVoter; import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.access.intercept.RequestKey; +import org.springframework.security.web.authentication.AnonymousProcessingFilter; import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.www.BasicProcessingFilter; @@ -126,6 +130,17 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { static final String EXPRESSION_HANDLER_CLASS = "org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"; private static final String EXPRESSION_HANDLER_ID = "_webExpressionHandler"; + final SecureRandom random; + + public HttpSecurityBeanDefinitionParser() { + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + // Shouldn't happen... + throw new RuntimeException("Failed find SHA1PRNG algorithm!"); + } + } + /** * The aim of this method is to build the list of filters which have been defined by the namespace elements * and attributes within the <http> configuration, along with any custom-filter's linked to user-defined @@ -454,12 +469,50 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { private BeanDefinition createAnonymousFilter(Element element, ParserContext pc) { Element anonymousElt = DomUtils.getChildElementByTagName(element, Elements.ANONYMOUS); - if (anonymousElt == null || !"false".equals(anonymousElt.getAttribute("enabled"))) { - return new AnonymousBeanDefinitionParser().parse(anonymousElt, pc); + if (anonymousElt != null && "false".equals(anonymousElt.getAttribute("enabled"))) { + return null; } - return null; + String grantedAuthority = null; + String username = null; + String key = null; + Object source = null; + if (element != null) { + grantedAuthority = element.getAttribute("granted-authority"); + username = element.getAttribute("username"); + key = element.getAttribute("key"); + source = pc.extractSource(element); + } + + if (!StringUtils.hasText(grantedAuthority)) { + grantedAuthority = "ROLE_ANONYMOUS"; + } + + if (!StringUtils.hasText(username)) { + username = "anonymousUser"; + } + + if (!StringUtils.hasText(key)) { + // Generate a random key for the Anonymous provider + key = Long.toString(random.nextLong()); + } + + RootBeanDefinition filter = new RootBeanDefinition(AnonymousProcessingFilter.class); + + PropertyValue keyPV = new PropertyValue("key", key); + filter.setSource(source); + filter.getPropertyValues().addPropertyValue("userAttribute", username + "," + grantedAuthority); + filter.getPropertyValues().addPropertyValue(keyPV); + + RootBeanDefinition provider = new RootBeanDefinition(AnonymousAuthenticationProvider.class); + provider.setSource(source); + provider.getPropertyValues().addPropertyValue(keyPV); + + pc.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER, provider); + ConfigUtils.addAuthenticationProvider(pc, BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER, element); + + return filter; } private FilterAndEntryPoint createBasicFilter(Element elt, ParserContext pc, boolean autoConfig) { @@ -804,7 +857,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { BeanDefinition openIDProvider = openIDProviderBuilder.getBeanDefinition(); pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_PROVIDER, openIDProvider); - ConfigUtils.addAuthenticationProvider(pc, BeanIds.OPEN_ID_PROVIDER); + ConfigUtils.addAuthenticationProvider(pc, BeanIds.OPEN_ID_PROVIDER, element); } if (openIDFilter != null) { diff --git a/config/src/main/java/org/springframework/security/config/LdapProviderBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/LdapProviderBeanDefinitionParser.java index 017961399e..1c9d26bd32 100644 --- a/config/src/main/java/org/springframework/security/config/LdapProviderBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/LdapProviderBeanDefinitionParser.java @@ -100,7 +100,7 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser { LdapUserServiceBeanDefinitionParser.parseUserDetailsClassOrUserMapperRef(elt, parserContext)); parserContext.getRegistry().registerBeanDefinition(BeanIds.LDAP_AUTHENTICATION_PROVIDER, ldapProvider.getBeanDefinition()); - ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.LDAP_AUTHENTICATION_PROVIDER); + ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.LDAP_AUTHENTICATION_PROVIDER, elt); return null; } diff --git a/config/src/main/java/org/springframework/security/config/RememberMeBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/RememberMeBeanDefinitionParser.java index 411283fd35..390d09b094 100644 --- a/config/src/main/java/org/springframework/security/config/RememberMeBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/RememberMeBeanDefinitionParser.java @@ -111,7 +111,11 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser { pc.getRegistry().registerAlias(rememberMeServicesRef, BeanIds.REMEMBER_ME_SERVICES); } - registerProvider(pc, source, key); + RootBeanDefinition provider = new RootBeanDefinition(RememberMeAuthenticationProvider.class); + provider.setSource(source); + provider.getPropertyValues().addPropertyValue(ATT_KEY, key); + pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER, provider); + ConfigUtils.addAuthenticationProvider(pc, BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER, element); BeanDefinition filter = createFilter(pc, source); pc.popAndRegisterContainingComponent(); @@ -123,15 +127,6 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser { return servicesName; } - private void registerProvider(ParserContext pc, Object source, String key) { - //BeanDefinition authManager = ConfigUtils.registerProviderManagerIfNecessary(pc); - RootBeanDefinition provider = new RootBeanDefinition(RememberMeAuthenticationProvider.class); - provider.setSource(source); - provider.getPropertyValues().addPropertyValue(ATT_KEY, key); - pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER, provider); - ConfigUtils.addAuthenticationProvider(pc, BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER); - } - private BeanDefinition createFilter(ParserContext pc, Object source) { RootBeanDefinition filter = new RootBeanDefinition(RememberMeProcessingFilter.class); filter.setSource(source); diff --git a/config/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java index 1aeb55950a..36ba702444 100644 --- a/config/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java @@ -43,7 +43,7 @@ public class X509BeanDefinitionParser implements BeanDefinitionParser { BeanDefinition provider = new RootBeanDefinition(PreAuthenticatedAuthenticationProvider.class); parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_AUTH_PROVIDER, provider); - ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.X509_AUTH_PROVIDER); + ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.X509_AUTH_PROVIDER, element); String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF); diff --git a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml index e482bd98a7..dc7e2272a7 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -31,6 +31,7 @@ + @@ -45,7 +46,6 @@ based on the role granted the ability to 'switch' to another user --> - diff --git a/samples/contacts/src/main/webapp/exitUser.jsp b/samples/contacts/src/main/webapp/exitUser.jsp index 8738d7bd74..c343fae4b2 100644 --- a/samples/contacts/src/main/webapp/exitUser.jsp +++ b/samples/contacts/src/main/webapp/exitUser.jsp @@ -37,8 +37,6 @@ - - diff --git a/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security.xml index 637354343f..499572b3c0 100644 --- a/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -38,6 +38,8 @@ --> + +