浏览代码

Delay AuthenticationPrincipalArgumentResolver Creation

Use ObjectProvider<AuthenticationPrincipalArgumentResolver> to delay its
lookup.

Closes gh-8613
Rob Winch 5 年之前
父节点
当前提交
748538d19f

+ 3 - 2
config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java

@@ -18,6 +18,7 @@ package org.springframework.security.config.annotation.web.reactive;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -87,11 +88,11 @@ class ServerHttpSecurityConfiguration {
 
 	@Bean
 	public WebFluxConfigurer authenticationPrincipalArgumentResolverConfigurer(
-			AuthenticationPrincipalArgumentResolver authenticationPrincipalArgumentResolver) {
+			ObjectProvider<AuthenticationPrincipalArgumentResolver> authenticationPrincipalArgumentResolver) {
 		return new WebFluxConfigurer() {
 			@Override
 			public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
-				configurer.addCustomResolver(authenticationPrincipalArgumentResolver);
+				configurer.addCustomResolver(authenticationPrincipalArgumentResolver.getObject());
 			}
 		};
 	}

+ 21 - 0
config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java

@@ -47,6 +47,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
+import org.springframework.security.web.reactive.result.method.annotation.AuthenticationPrincipalArgumentResolver;
 import org.springframework.security.web.reactive.result.view.CsrfRequestDataValueProcessor;
 import org.springframework.security.web.server.SecurityWebFilterChain;
 import org.springframework.security.web.server.WebFilterChainProxy;
@@ -59,6 +60,7 @@ import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.reactive.config.DelegatingWebFluxConfiguration;
 import org.springframework.web.reactive.config.EnableWebFlux;
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.result.view.AbstractView;
@@ -434,4 +436,23 @@ public class EnableWebFluxSecurityTests {
 		Child() {
 		}
 	}
+
+	@Test
+	// gh-8596
+	public void resolveAuthenticationPrincipalArgumentResolverFirstDoesNotCauseBeanCurrentlyInCreationException() {
+		this.spring.register(EnableWebFluxSecurityConfiguration.class,
+				ReactiveAuthenticationTestConfiguration.class,
+				DelegatingWebFluxConfiguration.class).autowire();
+	}
+
+	@EnableWebFluxSecurity
+	@Configuration(proxyBeanMethods = false)
+	static class EnableWebFluxSecurityConfiguration {
+		/**
+		 * It is necessary to Autowire AuthenticationPrincipalArgumentResolver because it triggers eager loading of
+		 * AuthenticationPrincipalArgumentResolver bean which causes BeanCurrentlyInCreationException
+		 */
+		@Autowired
+		AuthenticationPrincipalArgumentResolver resolver;
+	}
 }