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 11d6433ff3..6ebb0ffe89 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 @@ -20,12 +20,15 @@ import org.junit.Rule; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportResource; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.test.SpringTestRule; +import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; @@ -141,15 +144,8 @@ public class EnableWebFluxSecurityTests { } @EnableWebFluxSecurity + @Import(ReactiveAuthenticationTestConfiguration.class) static class Config { - @Bean - public ReactiveUserDetailsService userDetailsRepository() { - return new MapReactiveUserDetailsService(User.withUsername("user") - .password("password") - .roles("USER") - .build() - ); - } } @Test @@ -236,22 +232,21 @@ public class EnableWebFluxSecurityTests { } @EnableWebFluxSecurity + @Import(ReactiveAuthenticationTestConfiguration.class) static class MultiSecurityHttpConfig { - @Order(Ordered.HIGHEST_PRECEDENCE) @Bean public SecurityWebFilterChain apiHttpSecurity( + @Order(Ordered.HIGHEST_PRECEDENCE) + @Bean + public SecurityWebFilterChain apiHttpSecurity( ServerHttpSecurity http) { http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**")) .authorizeExchange().anyExchange().denyAll(); return http.build(); } - @Bean public SecurityWebFilterChain httpSecurity(ServerHttpSecurity http) { + @Bean + public SecurityWebFilterChain httpSecurity(ServerHttpSecurity http) { return http.build(); } - - @Bean public ReactiveUserDetailsService userDetailsRepository() { - return new MapReactiveUserDetailsService( - User.withUsername("user").password("password").roles("USER").build()); - } } private static DataBuffer toDataBuffer(String body) { diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationBuilder.java b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationBuilder.java index b44719133c..aa43f5de60 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationBuilder.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationBuilder.java @@ -18,25 +18,24 @@ package org.springframework.security.config.annotation.web.reactive; import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager; +import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration; import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.ReactiveUserDetailsService; /** * @author Rob Winch * @since 5.0 */ public class ServerHttpSecurityConfigurationBuilder { - public static final UserDetails USER = User.withUsername("user").password("password").roles("USER").build(); - public static final UserDetails ADMIN = User.withUsername("admin").password("password").roles("USER","ADMIN").build(); - public static ServerHttpSecurity http() { return new ServerHttpSecurityConfiguration().httpSecurity(); } public static ServerHttpSecurity httpWithDefaultAuthentication() { - ReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(new MapReactiveUserDetailsService(USER,ADMIN)); + ReactiveUserDetailsService reactiveUserDetailsService = ReactiveAuthenticationTestConfiguration + .userDetailsRepository(); + ReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager( + reactiveUserDetailsService); return http() .authenticationManager(authenticationManager); } diff --git a/config/src/test/java/org/springframework/security/config/users/ReactiveAuthenticationTestConfiguration.java b/config/src/test/java/org/springframework/security/config/users/ReactiveAuthenticationTestConfiguration.java new file mode 100644 index 0000000000..fcbb0d0ded --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/users/ReactiveAuthenticationTestConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.config.users; + +import org.junit.Test; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.PasswordEncodedUser; +import org.springframework.security.core.userdetails.ReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; + +/** + * @author Rob Winch + * @since 5.0 + */ +@Configuration +public class ReactiveAuthenticationTestConfiguration { + @Bean + public static ReactiveUserDetailsService userDetailsRepository() { + return new MapReactiveUserDetailsService(PasswordEncodedUser.user(), PasswordEncodedUser.admin()); + } +} diff --git a/core/src/main/java/org/springframework/security/authentication/UserDetailsRepositoryReactiveAuthenticationManager.java b/core/src/main/java/org/springframework/security/authentication/UserDetailsRepositoryReactiveAuthenticationManager.java index a5548c5e24..303fcb627e 100644 --- a/core/src/main/java/org/springframework/security/authentication/UserDetailsRepositoryReactiveAuthenticationManager.java +++ b/core/src/main/java/org/springframework/security/authentication/UserDetailsRepositoryReactiveAuthenticationManager.java @@ -19,7 +19,7 @@ package org.springframework.security.authentication; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.ReactiveUserDetailsService; -import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.util.Assert; import reactor.core.publisher.Mono; @@ -32,7 +32,7 @@ import reactor.core.scheduler.Schedulers; public class UserDetailsRepositoryReactiveAuthenticationManager implements ReactiveAuthenticationManager { private final ReactiveUserDetailsService repository; - private PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance(); + private PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); public UserDetailsRepositoryReactiveAuthenticationManager(ReactiveUserDetailsService reactiveUserDetailsService) { Assert.notNull(reactiveUserDetailsService, "userDetailsRepository cannot be null"); diff --git a/core/src/test/java/org/springframework/security/authentication/ReactiveUserDetailsServiceAuthenticationManagerTests.java b/core/src/test/java/org/springframework/security/authentication/ReactiveUserDetailsServiceAuthenticationManagerTests.java index d6b1cec741..3abb55a6f3 100644 --- a/core/src/test/java/org/springframework/security/authentication/ReactiveUserDetailsServiceAuthenticationManagerTests.java +++ b/core/src/test/java/org/springframework/security/authentication/ReactiveUserDetailsServiceAuthenticationManagerTests.java @@ -26,9 +26,11 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.PasswordEncodedUser; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.ReactiveUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -74,10 +76,13 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests { @Test public void authenticateWhenPasswordNotEqualThenBadCredentials() { - User user = new User(username, password, AuthorityUtils.createAuthorityList("ROLE_USER")); + UserDetails user = PasswordEncodedUser.withUsername(this.username) + .password(this.password) + .roles("USER") + .build(); when(repository.findByUsername(user.getUsername())).thenReturn(Mono.just(user)); - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password + "INVALID"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, this.password + "INVALID"); Mono authentication = manager.authenticate(token); StepVerifier @@ -88,7 +93,10 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests { @Test public void authenticateWhenSuccessThenSuccess() { - User user = new User(username, password, AuthorityUtils.createAuthorityList("ROLE_USER")); + UserDetails user = PasswordEncodedUser.withUsername(this.username) + .password(this.password) + .roles("USER") + .build(); when(repository.findByUsername(user.getUsername())).thenReturn(Mono.just(user)); UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); diff --git a/samples/javaconfig/hellowebflux-method/src/main/java/sample/SecurityConfig.java b/samples/javaconfig/hellowebflux-method/src/main/java/sample/SecurityConfig.java index acaefc3c8a..6d8784be5b 100644 --- a/samples/javaconfig/hellowebflux-method/src/main/java/sample/SecurityConfig.java +++ b/samples/javaconfig/hellowebflux-method/src/main/java/sample/SecurityConfig.java @@ -23,6 +23,7 @@ import org.springframework.security.config.annotation.web.reactive.EnableWebFlux import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.web.server.SecurityWebFilterChain; /** @@ -47,8 +48,9 @@ public class SecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsRepository() { - UserDetails rob = User.withUsername("rob").password("rob").roles("USER").build(); - UserDetails admin = User.withUsername("admin").password("admin").roles("USER","ADMIN").build(); + User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); + UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); + UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build(); return new MapReactiveUserDetailsService(rob, admin); } diff --git a/samples/javaconfig/hellowebflux/src/main/java/sample/HelloWebfluxSecurityConfig.java b/samples/javaconfig/hellowebflux/src/main/java/sample/HelloWebfluxSecurityConfig.java index f2d45e3a7a..474eb463de 100644 --- a/samples/javaconfig/hellowebflux/src/main/java/sample/HelloWebfluxSecurityConfig.java +++ b/samples/javaconfig/hellowebflux/src/main/java/sample/HelloWebfluxSecurityConfig.java @@ -31,7 +31,8 @@ public class HelloWebfluxSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsRepository() { - UserDetails user = User.withUsername("user") + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") .password("user") .roles("USER") .build(); diff --git a/samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnSecurityConfig.java b/samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnSecurityConfig.java index 6cb8faabea..3168162dca 100644 --- a/samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnSecurityConfig.java +++ b/samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnSecurityConfig.java @@ -31,7 +31,8 @@ public class HelloWebfluxFnSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsRepository() { - UserDetails user = User.withUsername("user") + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") .password("user") .roles("USER") .build();