소스 검색

SEC-1186: Make sure an Element is always supplied when registering the AuthenticationManager. Fixes broken tests.

Luke Taylor 16 년 전
부모
커밋
853b4c8753

+ 1 - 1
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;
     }

+ 1 - 1
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;
     }

+ 2 - 2
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);
     }

+ 2 - 1
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;
     }

+ 57 - 4
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) {

+ 1 - 1
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;
     }

+ 5 - 10
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);

+ 1 - 1
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);
 

+ 1 - 1
samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml

@@ -31,6 +31,7 @@
         <http-basic/>
         <logout logout-success-url="/index.jsp"/>
         <remember-me />
+        <custom-filter ref="switchUserProcessingFilter" position="SWITCH_USER_FILTER"/>
     </http>
 
     <authentication-provider>
@@ -45,7 +46,6 @@
         based on the role granted the ability to 'switch' to another user -->
     <!-- In this example 'rod' has ROLE_SUPERVISOR that can switch to regular ROLE_USER(s) -->
     <b:bean id="switchUserProcessingFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserProcessingFilter" autowire="byType">
-       <custom-filter position="SWITCH_USER_FILTER"/>
        <b:property name="targetUrl" value="/secure/index.htm"/>
     </b:bean>
 

+ 0 - 2
samples/contacts/src/main/webapp/exitUser.jsp

@@ -37,8 +37,6 @@
          </td></tr>
         <tr><td colspan='2'><input name="exit" type="submit" value="Exit"></td></tr>
       </table>
-
     </form>
-
   </body>
 </html>

+ 2 - 0
samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security.xml

@@ -38,6 +38,8 @@
         -->
     </http>
 
+    <authentication-manager alias="authManager"/>
+
     <!--
     Usernames/Passwords are
         rod/koala