Improve conditions for enabling WebFlux security
This commit correct a mistake where AuthenticationManager was used instead of ReactiveAuthenticationManager. It also expands the conditions so that WebFlux security will be enabled when the user has defined their own SecurityWebFilterChain. In such a situation no other security-related beans may be needed to use WebFlux security as things may have been configured directly using the DSL. Closes gh-37504
This commit is contained in:
		
							parent
							
								
									ff99de49c4
								
							
						
					
					
						commit
						4493958f13
					
				|  | @ -29,9 +29,10 @@ import org.springframework.boot.autoconfigure.security.SecurityProperties; | ||||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||||
| import org.springframework.context.annotation.Conditional; | import org.springframework.context.annotation.Conditional; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.ReactiveAuthenticationManager; | ||||||
| import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | ||||||
| import org.springframework.security.core.userdetails.ReactiveUserDetailsService; | import org.springframework.security.core.userdetails.ReactiveUserDetailsService; | ||||||
|  | import org.springframework.security.web.server.SecurityWebFilterChain; | ||||||
| import org.springframework.security.web.server.WebFilterChainProxy; | import org.springframework.security.web.server.WebFilterChainProxy; | ||||||
| import org.springframework.web.reactive.config.WebFluxConfigurer; | import org.springframework.web.reactive.config.WebFluxConfigurer; | ||||||
| 
 | 
 | ||||||
|  | @ -54,20 +55,20 @@ public class ReactiveSecurityAutoConfiguration { | ||||||
| 	@Configuration(proxyBeanMethods = false) | 	@Configuration(proxyBeanMethods = false) | ||||||
| 	@ConditionalOnMissingBean(WebFilterChainProxy.class) | 	@ConditionalOnMissingBean(WebFilterChainProxy.class) | ||||||
| 	@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) | 	@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) | ||||||
| 	@Conditional(ReactiveAuthenticationManagerCondition.class) | 	@Conditional(EnableWebFluxSecurityCondition.class) | ||||||
| 	@EnableWebFluxSecurity | 	@EnableWebFluxSecurity | ||||||
| 	static class EnableWebFluxSecurityConfiguration { | 	static class EnableWebFluxSecurityConfiguration { | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static final class ReactiveAuthenticationManagerCondition extends AnyNestedCondition { | 	static final class EnableWebFluxSecurityCondition extends AnyNestedCondition { | ||||||
| 
 | 
 | ||||||
| 		ReactiveAuthenticationManagerCondition() { | 		EnableWebFluxSecurityCondition() { | ||||||
| 			super(ConfigurationPhase.REGISTER_BEAN); | 			super(ConfigurationPhase.REGISTER_BEAN); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		@ConditionalOnBean(AuthenticationManager.class) | 		@ConditionalOnBean(ReactiveAuthenticationManager.class) | ||||||
| 		static final class ConditionalOnAuthenticationManagerBean { | 		static final class ConditionalOnReactiveAuthenticationManagerBean { | ||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -76,6 +77,11 @@ public class ReactiveSecurityAutoConfiguration { | ||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		@ConditionalOnBean(SecurityWebFilterChain.class) | ||||||
|  | 		static final class ConditionalOnSecurityWebFilterChain { | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,9 +25,11 @@ import org.springframework.boot.test.context.FilteredClassLoader; | ||||||
| import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; | import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.security.authentication.ReactiveAuthenticationManager; | ||||||
| import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | ||||||
| import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; | import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; | ||||||
| import org.springframework.security.core.userdetails.User; | import org.springframework.security.core.userdetails.User; | ||||||
|  | import org.springframework.security.web.server.SecurityWebFilterChain; | ||||||
| import org.springframework.security.web.server.WebFilterChainProxy; | import org.springframework.security.web.server.WebFilterChainProxy; | ||||||
| import org.springframework.web.reactive.config.WebFluxConfigurer; | import org.springframework.web.reactive.config.WebFluxConfigurer; | ||||||
| 
 | 
 | ||||||
|  | @ -57,11 +59,24 @@ class ReactiveSecurityAutoConfigurationTests { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Test | 	@Test | ||||||
| 	void enablesWebFluxSecurity() { | 	void enablesWebFluxSecurityWhenUserDetailsServiceIsPresent() { | ||||||
| 		this.contextRunner.withUserConfiguration(UserDetailsServiceConfiguration.class) | 		this.contextRunner.withUserConfiguration(UserDetailsServiceConfiguration.class) | ||||||
| 			.run((context) -> assertThat(context).getBean(WebFilterChainProxy.class).isNotNull()); | 			.run((context) -> assertThat(context).getBean(WebFilterChainProxy.class).isNotNull()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void enablesWebFluxSecurityWhenReactiveAuthenticationManagerIsPresent() { | ||||||
|  | 		this.contextRunner | ||||||
|  | 			.withBean(ReactiveAuthenticationManager.class, () -> mock(ReactiveAuthenticationManager.class)) | ||||||
|  | 			.run((context) -> assertThat(context).getBean(WebFilterChainProxy.class).isNotNull()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void enablesWebFluxSecurityWhenSecurityWebFilterChainIsPresent() { | ||||||
|  | 		this.contextRunner.withBean(SecurityWebFilterChain.class, () -> mock(SecurityWebFilterChain.class)) | ||||||
|  | 			.run((context) -> assertThat(context).getBean(WebFilterChainProxy.class).isNotNull()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@Test | 	@Test | ||||||
| 	void autoConfigurationIsConditionalOnClass() { | 	void autoConfigurationIsConditionalOnClass() { | ||||||
| 		this.contextRunner | 		this.contextRunner | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue