From be0081290ba7f1008a592bb61d0ca9784dc656cc Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Wed, 30 Aug 2017 10:02:00 -0500 Subject: [PATCH] EnableWebFluxSecurity uses PasswordEncoder Bean --- .../reactive/HttpSecurityConfiguration.java | 19 ++++++-- .../reactive/EnableWebFluxSecurityTests.java | 47 +++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/reactive/HttpSecurityConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/web/reactive/HttpSecurityConfiguration.java index 92d5e2c790..af7c55518a 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/reactive/HttpSecurityConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/reactive/HttpSecurityConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.security.authentication.ReactiveAuthenticationManager import org.springframework.security.authentication.UserDetailsRepositoryAuthenticationManager; import org.springframework.security.config.web.server.HttpSecurity; import org.springframework.security.core.userdetails.UserDetailsRepository; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.reactive.result.method.annotation.AuthenticationPrincipalArgumentResolver; import org.springframework.security.web.server.context.WebSessionSecurityContextRepository; import org.springframework.web.reactive.config.WebFluxConfigurer; @@ -50,6 +51,9 @@ public class HttpSecurityConfiguration implements WebFluxConfigurer { @Autowired(required = false) private UserDetailsRepository userDetailsRepository; + @Autowired(required = false) + private PasswordEncoder passwordEncoder; + @Override public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) { configurer.addCustomResolver(authenticationPrincipalArgumentResolver()); @@ -57,7 +61,7 @@ public class HttpSecurityConfiguration implements WebFluxConfigurer { @Bean public AuthenticationPrincipalArgumentResolver authenticationPrincipalArgumentResolver() { - return new AuthenticationPrincipalArgumentResolver(adapterRegistry); + return new AuthenticationPrincipalArgumentResolver(this.adapterRegistry); } @Bean(HTTPSECURITY_BEAN_NAME) @@ -71,11 +75,16 @@ public class HttpSecurityConfiguration implements WebFluxConfigurer { } private ReactiveAuthenticationManager authenticationManager() { - if(authenticationManager != null) { - return authenticationManager; + if(this.authenticationManager != null) { + return this.authenticationManager; } - if(userDetailsRepository != null) { - return new UserDetailsRepositoryAuthenticationManager(userDetailsRepository); + if(this.userDetailsRepository != null) { + UserDetailsRepositoryAuthenticationManager manager = + new UserDetailsRepositoryAuthenticationManager(this.userDetailsRepository); + if(this.passwordEncoder != null) { + manager.setPasswordEncoder(this.passwordEncoder); + } + return manager; } return null; } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java index 1c926bb0f1..658f99ea67 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/EnableWebFluxSecurityTests.java @@ -33,6 +33,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.MapUserDetailsRepository; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsRepository; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.test.web.reactive.server.WebTestClientBuilder; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.WebFilterChainFilter; @@ -127,6 +129,51 @@ public class EnableWebFluxSecurityTests { } } + @RunWith(SpringRunner.class) + public static class CustomPasswordEncoder { + @Autowired + WebFilterChainFilter springSecurityFilterChain; + + @Test + public void passwordEncoderBeanIsUsed() { + WebTestClient client = WebTestClientBuilder.bindToWebFilters( + springSecurityFilterChain, + (exchange,chain) -> + Mono.currentContext() + .flatMap( c -> c.>get(Authentication.class)) + .flatMap( principal -> exchange.getResponse() + .writeWith(Mono.just(toDataBuffer(principal.getName())))) + ) + .filter(basicAuthentication()) + .build(); + + client + .get() + .uri("/") + .attributes(basicAuthenticationCredentials("user","password")) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).consumeWith( result -> assertThat(result.getResponseBody()).isEqualTo("user")); + } + + @EnableWebFluxSecurity + static class Config { + @Bean + public UserDetailsRepository userDetailsRepository(PasswordEncoder encoder) { + return new MapUserDetailsRepository(User.withUsername("user") + .password(encoder.encode("password")) + .roles("USER") + .build() + ); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + } + } + @RunWith(SpringRunner.class) public static class MultiHttpSecurity { @Autowired