Browse Source

SEC-2329: JC @Autowire(required=false) AuthenticationTrustResolver

Java Configuration now allows optional @Autowire of
AuthenticationTrustResolver. In the WebSecurityConfigurerAdapter this is
done by populating AuthenticationTrustResolver as a sharedObject.
Rob Winch 12 năm trước cách đây
mục cha
commit
f294480e6b
11 tập tin đã thay đổi với 200 bổ sung44 xóa
  1. 16 5
      config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java
  2. 9 0
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.java
  3. 17 10
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractInterceptUrlConfigurer.java
  4. 22 6
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java
  5. 8 1
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java
  6. 17 7
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java
  7. 7 4
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/UrlAuthorizationConfigurer.java
  8. 37 10
      config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy
  9. 22 1
      config/src/test/groovy/org/springframework/security/config/annotation/web/WebSecurityConfigurerAdapterTests.groovy
  10. 22 0
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy
  11. 23 0
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.groovy

+ 16 - 5
config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java

@@ -62,6 +62,7 @@ import org.springframework.security.access.vote.AffirmativeBased;
 import org.springframework.security.access.vote.AuthenticatedVoter;
 import org.springframework.security.access.vote.RoleVoter;
 import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
 import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
@@ -85,6 +86,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
             throw new IllegalStateException(ObjectPostProcessor.class.getName()+ " is a required bean. Ensure you have used @"+EnableGlobalMethodSecurity.class.getName());
         }
     };
+    private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
     private AuthenticationManager authenticationManager;
     private AuthenticationManagerBuilder auth = new AuthenticationManagerBuilder(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR);
     private boolean disableAuthenticationRegistry;
@@ -192,16 +194,20 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
     }
 
     /**
-     * Provide a {@link MethodSecurityExpressionHandler} that is
-     * registered with the {@link ExpressionBasedPreInvocationAdvice}. The default is
-     * {@link DefaultMethodSecurityExpressionHandler}
+     * Provide a {@link MethodSecurityExpressionHandler} that is registered with
+     * the {@link ExpressionBasedPreInvocationAdvice}. The default is
+     * {@link DefaultMethodSecurityExpressionHandler} which optionally will
+     * Autowire an {@link AuthenticationTrustResolver}.
      *
-     * <p>Subclasses may override this method to provide a custom {@link MethodSecurityExpressionHandler}</p>
+     * <p>
+     * Subclasses may override this method to provide a custom
+     * {@link MethodSecurityExpressionHandler}
+     * </p>
      *
      * @return
      */
     protected MethodSecurityExpressionHandler expressionHandler() {
-        return new DefaultMethodSecurityExpressionHandler();
+        return defaultMethodExpressionHandler;
     }
 
     /**
@@ -339,6 +345,11 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
                 .fromMap(annotationAttributes);
     }
 
+    @Autowired(required = false)
+    public void setAuthenticationTrustResolver(AuthenticationTrustResolver trustResolver) {
+        this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
+    }
+
     @Autowired
     public void setApplicationContext(ApplicationContext context) {
         this.context = context;

+ 9 - 0
config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.java

@@ -24,6 +24,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationTrustResolver;
+import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
 import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
 import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.SecurityConfigurer;
@@ -76,6 +78,7 @@ public abstract class WebSecurityConfigurerAdapter implements SecurityConfigurer
     private boolean disableAuthenticationRegistration;
     private boolean authenticationManagerInitialized;
     private AuthenticationManager authenticationManager;
+    private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
     private HttpSecurity http;
     private boolean disableDefaults;
 
@@ -153,6 +156,7 @@ public abstract class WebSecurityConfigurerAdapter implements SecurityConfigurer
         http.setSharedObject(UserDetailsService.class, userDetailsService());
         http.setSharedObject(ApplicationContext.class, context);
         http.setSharedObject(ContentNegotiationStrategy.class, contentNegotiationStrategy);
+        http.setSharedObject(AuthenticationTrustResolver.class, trustResolver);
         if(!disableDefaults) {
             http
                 .csrf().and()
@@ -312,6 +316,11 @@ public abstract class WebSecurityConfigurerAdapter implements SecurityConfigurer
         this.context = context;
     }
 
+    @Autowired(required=false)
+    public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
+        this.trustResolver = trustResolver;
+    }
+
     @Autowired(required=false)
     public void setContentNegotationStrategy(ContentNegotiationStrategy contentNegotiationStrategy) {
         this.contentNegotiationStrategy = contentNegotiationStrategy;

+ 17 - 10
config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractInterceptUrlConfigurer.java

@@ -98,11 +98,11 @@ abstract class AbstractInterceptUrlConfigurer<H extends HttpSecurityBuilder<H>,C
 
     @Override
     public void configure(H http) throws Exception {
-        FilterInvocationSecurityMetadataSource metadataSource = createMetadataSource();
+        FilterInvocationSecurityMetadataSource metadataSource = createMetadataSource(http);
         if(metadataSource == null) {
             return;
         }
-        FilterSecurityInterceptor securityInterceptor = createFilterSecurityInterceptor(metadataSource, http.getSharedObject(AuthenticationManager.class));
+        FilterSecurityInterceptor securityInterceptor = createFilterSecurityInterceptor(http, metadataSource, http.getSharedObject(AuthenticationManager.class));
         if(filterSecurityInterceptorOncePerRequest != null) {
             securityInterceptor.setObserveOncePerRequest(filterSecurityInterceptorOncePerRequest);
         }
@@ -115,38 +115,44 @@ abstract class AbstractInterceptUrlConfigurer<H extends HttpSecurityBuilder<H>,C
      * Subclasses should implement this method to provide a {@link FilterInvocationSecurityMetadataSource} for the
      * {@link FilterSecurityInterceptor}.
      *
+     * @param http the builder to use
+     *
      * @return the {@link FilterInvocationSecurityMetadataSource} to set on the {@link FilterSecurityInterceptor}.
      *         Cannot be null.
      */
-    abstract FilterInvocationSecurityMetadataSource createMetadataSource();
+    abstract FilterInvocationSecurityMetadataSource createMetadataSource(H http);
 
     /**
      * Subclasses should implement this method to provide the {@link AccessDecisionVoter} instances used to create the
      * default {@link AccessDecisionManager}
      *
+     * @param http the builder to use
+     *
      * @return the {@link AccessDecisionVoter} instances used to create the
      *         default {@link AccessDecisionManager}
      */
     @SuppressWarnings("rawtypes")
-    abstract List<AccessDecisionVoter> getDecisionVoters();
+    abstract List<AccessDecisionVoter> getDecisionVoters(H http);
 
     /**
      * Creates the default {@code AccessDecisionManager}
      * @return the default {@code AccessDecisionManager}
      */
-    private AccessDecisionManager createDefaultAccessDecisionManager() {
-        return new AffirmativeBased(getDecisionVoters());
+    private AccessDecisionManager createDefaultAccessDecisionManager(H http) {
+        return new AffirmativeBased(getDecisionVoters(http));
     }
 
     /**
      * If currently null, creates a default {@link AccessDecisionManager} using
      * {@link #createDefaultAccessDecisionManager()}. Otherwise returns the {@link AccessDecisionManager}.
      *
+     * @param http the builder to use
+     *
      * @return the {@link AccessDecisionManager} to use
      */
-    private AccessDecisionManager getAccessDecisionManager() {
+    private AccessDecisionManager getAccessDecisionManager(H http) {
         if (accessDecisionManager == null) {
-            accessDecisionManager = createDefaultAccessDecisionManager();
+            accessDecisionManager = createDefaultAccessDecisionManager(http);
         }
         return accessDecisionManager;
     }
@@ -154,16 +160,17 @@ abstract class AbstractInterceptUrlConfigurer<H extends HttpSecurityBuilder<H>,C
     /**
      * Creates the {@link FilterSecurityInterceptor}
      *
+     * @param http the builder to use
      * @param metadataSource the {@link FilterInvocationSecurityMetadataSource} to use
      * @param authenticationManager the {@link AuthenticationManager} to use
      * @return the {@link FilterSecurityInterceptor}
      * @throws Exception
      */
-    private FilterSecurityInterceptor createFilterSecurityInterceptor(FilterInvocationSecurityMetadataSource metadataSource,
+    private FilterSecurityInterceptor createFilterSecurityInterceptor(H http, FilterInvocationSecurityMetadataSource metadataSource,
                                                                       AuthenticationManager authenticationManager) throws Exception {
         FilterSecurityInterceptor securityInterceptor = new FilterSecurityInterceptor();
         securityInterceptor.setSecurityMetadataSource(metadataSource);
-        securityInterceptor.setAccessDecisionManager(getAccessDecisionManager());
+        securityInterceptor.setAccessDecisionManager(getAccessDecisionManager(http));
         securityInterceptor.setAuthenticationManager(authenticationManager);
         securityInterceptor.afterPropertiesSet();
         return securityInterceptor;

+ 22 - 6
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java

@@ -24,6 +24,7 @@ import org.springframework.security.access.AccessDecisionVoter;
 import org.springframework.security.access.ConfigAttribute;
 import org.springframework.security.access.SecurityConfig;
 import org.springframework.security.access.expression.SecurityExpressionHandler;
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -56,7 +57,9 @@ import org.springframework.util.StringUtils;
  *
  * <h2>Shared Objects Used</h2>
  *
- * No shared objects are used.
+ * <ul>
+ * <li>{@link AuthenticationTrustResolver} is optionally used to populate the {@link DefaultWebSecurityExpressionHandler}</li>
+ * </ul>
  *
  * @param <H> the type of {@link HttpSecurityBuilder} that is being configured
  *
@@ -72,7 +75,7 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
     private static final String fullyAuthenticated = "fullyAuthenticated";
     private static final String rememberMe = "rememberMe";
 
-    private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();
+    private SecurityExpressionHandler<FilterInvocation> expressionHandler;
 
     /**
      * Creates a new instance
@@ -110,21 +113,21 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
 
     @Override
     @SuppressWarnings("rawtypes")
-    final List<AccessDecisionVoter> getDecisionVoters() {
+    final List<AccessDecisionVoter> getDecisionVoters(H http) {
         List<AccessDecisionVoter> decisionVoters = new ArrayList<AccessDecisionVoter>();
         WebExpressionVoter expressionVoter = new WebExpressionVoter();
-        expressionVoter.setExpressionHandler(expressionHandler);
+        expressionVoter.setExpressionHandler(getExpressionHandler(http));
         decisionVoters.add(expressionVoter);
         return decisionVoters;
     }
 
     @Override
-    final ExpressionBasedFilterInvocationSecurityMetadataSource createMetadataSource() {
+    final ExpressionBasedFilterInvocationSecurityMetadataSource createMetadataSource(H http) {
         LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = createRequestMap();
         if(requestMap.isEmpty()) {
             throw new IllegalStateException("At least one mapping is required (i.e. authorizeRequests().anyRequest.authenticated())");
         }
-        return new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, expressionHandler);
+        return new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, getExpressionHandler(http));
     }
 
     /**
@@ -141,6 +144,19 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
         return this;
     }
 
+    private SecurityExpressionHandler<FilterInvocation> getExpressionHandler(H http) {
+        if(expressionHandler == null) {
+            DefaultWebSecurityExpressionHandler defaultHandler = new DefaultWebSecurityExpressionHandler();
+            AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
+            if(trustResolver != null) {
+                defaultHandler.setTrustResolver(trustResolver);
+            }
+            expressionHandler = defaultHandler;
+        }
+
+        return expressionHandler;
+    }
+
     private static String hasRole(String role) {
         Assert.notNull(role, "role cannot be null");
         if (role.startsWith("ROLE_")) {

+ 8 - 1
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java

@@ -20,6 +20,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.core.context.SecurityContext;
@@ -45,7 +46,9 @@ import org.springframework.security.web.servletapi.SecurityContextHolderAwareReq
  *
  * <h2>Shared Objects Used</h2>
  *
- * No shared Objects are used.
+ * <ul>
+ * <li>{@link AuthenticationTrustResolver} is optionally used to populate the {@link SecurityContextHolderAwareRequestFilter}</li>
+ * </ul>
  *
  * @author Rob Winch
  * @since 3.2
@@ -75,6 +78,10 @@ public final class ServletApiConfigurer<H extends HttpSecurityBuilder<H>> extend
         LogoutConfigurer<H> logoutConf = http.getConfigurer(LogoutConfigurer.class);
         List<LogoutHandler> logoutHandlers = logoutConf == null ? null : logoutConf.getLogoutHandlers();
         securityContextRequestFilter.setLogoutHandlers(logoutHandlers);
+        AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
+        if(trustResolver != null) {
+            securityContextRequestFilter.setTrustResolver(trustResolver);
+        }
         securityContextRequestFilter = postProcess(securityContextRequestFilter);
         http.addFilter(securityContextRequestFilter);
     }

+ 17 - 7
config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

@@ -22,6 +22,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.http.SessionCreationPolicy;
@@ -71,6 +72,7 @@ import org.springframework.util.Assert;
  *
  * <ul>
  * <li>{@link SecurityContextRepository}</li>
+ * <li>{@link AuthenticationTrustResolver} is optionally used to populate the {@link HttpSessionSecurityContextRepository} and {@link SessionManagementFilter}</li>
  * </ul>
  *
  * @author Rob Winch
@@ -337,28 +339,32 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
     }
 
     @Override
-    public void init(H builder) throws Exception {
-        SecurityContextRepository securityContextRepository = builder.getSharedObject(SecurityContextRepository.class);
+    public void init(H http) throws Exception {
+        SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
         boolean stateless = isStateless();
 
         if(securityContextRepository == null) {
             if(stateless) {
-                builder.setSharedObject(SecurityContextRepository.class, new NullSecurityContextRepository());
+                http.setSharedObject(SecurityContextRepository.class, new NullSecurityContextRepository());
             } else {
                 HttpSessionSecurityContextRepository httpSecurityRepository = new HttpSessionSecurityContextRepository();
                 httpSecurityRepository.setDisableUrlRewriting(!enableSessionUrlRewriting);
                 httpSecurityRepository.setAllowSessionCreation(isAllowSessionCreation());
-                builder.setSharedObject(SecurityContextRepository.class, httpSecurityRepository);
+                AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
+                if(trustResolver != null) {
+                    httpSecurityRepository.setTrustResolver(trustResolver);
+                }
+                http.setSharedObject(SecurityContextRepository.class, httpSecurityRepository);
             }
         }
 
-        RequestCache requestCache = builder.getSharedObject(RequestCache.class);
+        RequestCache requestCache = http.getSharedObject(RequestCache.class);
         if(requestCache == null) {
             if(stateless) {
-                builder.setSharedObject(RequestCache.class, new NullRequestCache());
+                http.setSharedObject(RequestCache.class, new NullRequestCache());
             }
         }
-        builder.setSharedObject(SessionAuthenticationStrategy.class, getSessionAuthenticationStrategy());
+        http.setSharedObject(SessionAuthenticationStrategy.class, getSessionAuthenticationStrategy());
     }
 
     @Override
@@ -371,6 +377,10 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
         if(invalidSessionUrl != null) {
             sessionManagementFilter.setInvalidSessionStrategy(new SimpleRedirectInvalidSessionStrategy(invalidSessionUrl));
         }
+        AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
+        if(trustResolver != null) {
+            sessionManagementFilter.setTrustResolver(trustResolver);
+        }
         sessionManagementFilter = postProcess(sessionManagementFilter);
 
         http.addFilter(sessionManagementFilter);

+ 7 - 4
config/src/main/java/org/springframework/security/config/annotation/web/configurers/UrlAuthorizationConfigurer.java

@@ -84,10 +84,12 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>,
      * Creates the default {@link AccessDecisionVoter} instances used if an
      * {@link AccessDecisionManager} was not specified using
      * {@link #accessDecisionManager(AccessDecisionManager)}.
+     *
+     * @param http the builder to use
      */
     @Override
     @SuppressWarnings("rawtypes")
-    final List<AccessDecisionVoter> getDecisionVoters() {
+    final List<AccessDecisionVoter> getDecisionVoters(H http) {
         List<AccessDecisionVoter> decisionVoters = new ArrayList<AccessDecisionVoter>();
         decisionVoters.add(new RoleVoter());
         decisionVoters.add(new AuthenticatedVoter());
@@ -96,11 +98,12 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>,
 
     /**
      * Creates the {@link FilterInvocationSecurityMetadataSource} to use. The
-     * implementation is a {@link DefaultFilterInvocationSecurityMetadataSource}
-     * .
+     * implementation is a {@link DefaultFilterInvocationSecurityMetadataSource}.
+     *
+     * @param http the builder to use
      */
     @Override
-    FilterInvocationSecurityMetadataSource createMetadataSource() {
+    FilterInvocationSecurityMetadataSource createMetadataSource(H http) {
         return new DefaultFilterInvocationSecurityMetadataSource(createRequestMap());
     }
 

+ 37 - 10
config/src/test/groovy/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfigurationTests.groovy

@@ -18,22 +18,21 @@ package org.springframework.security.config.annotation.method.configuration
 import static org.fest.assertions.Assertions.assertThat
 import static org.junit.Assert.fail
 
-import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInterceptor
 import org.springframework.context.ApplicationContext
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.context.ApplicationListener
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
 import org.springframework.security.access.AccessDecisionManager
-import org.springframework.security.access.AccessDeniedException
-import org.springframework.security.access.ConfigAttribute
+import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler
+import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
 import org.springframework.security.authentication.AuthenticationManager
+import org.springframework.security.authentication.AuthenticationTrustResolver
 import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
+import org.springframework.security.authentication.event.AuthenticationSuccessEvent
 import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
-import org.springframework.security.config.annotation.web.WebSecurityConfigurerAdapterTests.InMemoryAuthWithWebSecurityConfigurerAdapter
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
 import org.springframework.security.core.Authentication
 import org.springframework.security.core.authority.AuthorityUtils
 
@@ -82,4 +81,32 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
     AuthenticationManager getAuthenticationManager() {
         context.getBean(MethodInterceptor).authenticationManager
     }
+
+    def "AuthenticationTrustResolver autowires"() {
+        setup:
+            CustomTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
+        when:
+            loadConfig(CustomTrustResolverConfig)
+            def preAdviceVoter = context.getBean(MethodInterceptor).accessDecisionManager.decisionVoters.find { it instanceof PreInvocationAuthorizationAdviceVoter}
+        then:
+            preAdviceVoter.preAdvice.expressionHandler.trustResolver == CustomTrustResolverConfig.TR
+    }
+
+    @Configuration
+    @EnableGlobalMethodSecurity(prePostEnabled = true)
+    static class CustomTrustResolverConfig extends GlobalMethodSecurityConfiguration {
+        static AuthenticationTrustResolver TR
+
+        @Override
+        protected void registerAuthentication(AuthenticationManagerBuilder auth)
+                throws Exception {
+            auth
+                .inMemoryAuthentication()
+        }
+
+        @Bean
+        public AuthenticationTrustResolver tr() {
+            return TR
+        }
+    }
 }

+ 22 - 1
config/src/test/groovy/org/springframework/security/config/annotation/web/WebSecurityConfigurerAdapterTests.groovy

@@ -29,6 +29,7 @@ import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
 import org.springframework.security.authentication.AuthenticationManager
 import org.springframework.security.authentication.AuthenticationProvider
+import org.springframework.security.authentication.AuthenticationTrustResolver
 import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
 import org.springframework.security.authentication.event.AuthenticationSuccessEvent
@@ -41,7 +42,7 @@ import org.springframework.security.core.Authentication
 import org.springframework.security.core.userdetails.UserDetailsService
 import org.springframework.security.core.userdetails.UsernameNotFoundException
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
-import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
+import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
 import org.springframework.web.accept.ContentNegotiationStrategy
 import org.springframework.web.accept.HeaderContentNegotiationStrategy
 import org.springframework.web.filter.OncePerRequestFilter
@@ -266,4 +267,24 @@ class WebSecurityConfigurerAdapterTests extends BaseSpringSpec {
             chain.doFilter(request,response)
         }
     }
+
+    def "AuthenticationTrustResolver populated as defaultObject"() {
+        setup:
+            CustomTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
+        when:
+            loadConfig(CustomTrustResolverConfig)
+        then:
+            context.getBean(CustomTrustResolverConfig).http.getSharedObject(AuthenticationTrustResolver) == CustomTrustResolverConfig.TR
+    }
+
+    @Configuration
+    @EnableWebSecurity
+    static class CustomTrustResolverConfig extends WebSecurityConfigurerAdapter {
+        static AuthenticationTrustResolver TR
+
+        @Bean
+        public AuthenticationTrustResolver tr() {
+            return TR
+        }
+    }
 }

+ 22 - 0
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy

@@ -18,6 +18,7 @@ package org.springframework.security.config.annotation.web.configurers
 import groovy.transform.CompileStatic
 
 import org.springframework.context.annotation.Configuration
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.config.annotation.AnyObjectPostProcessor
 import org.springframework.security.config.annotation.BaseSpringSpec
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
@@ -132,4 +133,25 @@ class ServletApiConfigurerTests extends BaseSpringSpec {
                 .exceptionHandling()
         }
     }
+
+    def "use sharedObject trustResolver"() {
+        setup:
+            SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
+        when:
+            loadConfig(SharedTrustResolverConfig)
+        then:
+            findFilter(SecurityContextHolderAwareRequestFilter).trustResolver == SharedTrustResolverConfig.TR
+    }
+
+    @Configuration
+    @EnableWebSecurity
+    static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
+        static AuthenticationTrustResolver TR
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .setSharedObject(AuthenticationTrustResolver, TR)
+        }
+    }
 }

+ 23 - 0
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.groovy

@@ -21,6 +21,7 @@ import org.springframework.context.annotation.Configuration
 import org.springframework.mock.web.MockFilterChain
 import org.springframework.mock.web.MockHttpServletRequest
 import org.springframework.mock.web.MockHttpServletResponse
+import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.config.annotation.AnyObjectPostProcessor
 import org.springframework.security.config.annotation.BaseSpringSpec
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
@@ -217,4 +218,26 @@ class SessionManagementConfigurerTests extends BaseSpringSpec {
         and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor"
             1 * opp.postProcess(_ as RegisterSessionAuthenticationStrategy) >> {RegisterSessionAuthenticationStrategy o -> o}
     }
+
+    def "use sharedObject trustResolver"() {
+        setup:
+            SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
+        when:
+            loadConfig(SharedTrustResolverConfig)
+        then:
+            findFilter(SecurityContextPersistenceFilter).repo.trustResolver == SharedTrustResolverConfig.TR
+            findFilter(SessionManagementFilter).trustResolver == SharedTrustResolverConfig.TR
+    }
+
+    @Configuration
+    @EnableWebSecurity
+    static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
+        static AuthenticationTrustResolver TR
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .setSharedObject(AuthenticationTrustResolver, TR)
+        }
+    }
 }