Add PasswordEncoder for UserDetailsRepositoryAuthenticationManager

This commit is contained in:
Rob Winch 2017-08-29 21:19:42 -05:00
parent 9f2ea90f0d
commit a563689e6c
2 changed files with 46 additions and 1 deletions

View File

@ -18,9 +18,12 @@
package org.springframework.security.authentication; package org.springframework.security.authentication;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsRepository; import org.springframework.security.core.userdetails.UserDetailsRepository;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -31,6 +34,8 @@ import reactor.core.publisher.Mono;
public class UserDetailsRepositoryAuthenticationManager implements ReactiveAuthenticationManager { public class UserDetailsRepositoryAuthenticationManager implements ReactiveAuthenticationManager {
private final UserDetailsRepository repository; private final UserDetailsRepository repository;
private PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
public UserDetailsRepositoryAuthenticationManager(UserDetailsRepository userDetailsRepository) { public UserDetailsRepositoryAuthenticationManager(UserDetailsRepository userDetailsRepository) {
Assert.notNull(userDetailsRepository, "userDetailsRepository cannot be null"); Assert.notNull(userDetailsRepository, "userDetailsRepository cannot be null");
this.repository = userDetailsRepository; this.repository = userDetailsRepository;
@ -41,8 +46,13 @@ public class UserDetailsRepositoryAuthenticationManager implements ReactiveAuthe
final String username = authentication.getName(); final String username = authentication.getName();
return repository return repository
.findByUsername(username) .findByUsername(username)
.filter( u -> u.getPassword().equals(authentication.getCredentials())) .filter( u -> this.passwordEncoder.matches((String) authentication.getCredentials(), u.getPassword()))
.switchIfEmpty( Mono.error(new BadCredentialsException("Invalid Credentials")) ) .switchIfEmpty( Mono.error(new BadCredentialsException("Invalid Credentials")) )
.map( u -> new UsernamePasswordAuthenticationToken(u, u.getPassword(), u.getAuthorities()) ); .map( u -> new UsernamePasswordAuthenticationToken(u, u.getPassword(), u.getAuthorities()) );
} }
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
this.passwordEncoder = passwordEncoder;
}
} }

View File

@ -16,6 +16,7 @@
package org.springframework.security.authentication; package org.springframework.security.authentication;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.junit.Before; import org.junit.Before;
@ -28,6 +29,7 @@ import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsRepository; import org.springframework.security.core.userdetails.UserDetailsRepository;
import org.springframework.security.crypto.password.PasswordEncoder;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
@ -39,6 +41,8 @@ import reactor.test.StepVerifier;
public class UserDetailsRepositoryAuthenticationManagerTests { public class UserDetailsRepositoryAuthenticationManagerTests {
@Mock @Mock
UserDetailsRepository repository; UserDetailsRepository repository;
@Mock
PasswordEncoder passwordEncoder;
UserDetailsRepositoryAuthenticationManager manager; UserDetailsRepositoryAuthenticationManager manager;
String username; String username;
String password; String password;
@ -94,4 +98,35 @@ public class UserDetailsRepositoryAuthenticationManagerTests {
assertThat(authentication).isEqualTo(authentication); assertThat(authentication).isEqualTo(authentication);
} }
@Test
public void authenticateWhenPasswordEncoderAndSuccessThenSuccess() {
this.manager.setPasswordEncoder(this.passwordEncoder);
when(this.passwordEncoder.matches(any(), any())).thenReturn(true);
User user = new User(this.username, this.password, AuthorityUtils.createAuthorityList("ROLE_USER"));
when(this.repository.findByUsername(user.getUsername())).thenReturn(Mono.just(user));
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
this.username, this.password);
Authentication authentication = this.manager.authenticate(token).block();
assertThat(authentication).isEqualTo(authentication);
}
@Test
public void authenticateWhenPasswordEncoderAndFailThenFail() {
this.manager.setPasswordEncoder(this.passwordEncoder);
when(this.passwordEncoder.matches(any(), any())).thenReturn(false);
User user = new User(this.username, this.password, AuthorityUtils.createAuthorityList("ROLE_USER"));
when(this.repository.findByUsername(user.getUsername())).thenReturn(Mono.just(user));
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
this.username, this.password);
Mono<Authentication> authentication = this.manager.authenticate(token);
StepVerifier
.create(authentication)
.expectError(BadCredentialsException.class)
.verify();
}
} }