浏览代码

Add PasswordEncoder for UserDetailsRepositoryAuthenticationManager

Rob Winch 8 年之前
父节点
当前提交
a563689e6c

+ 11 - 1
core/src/main/java/org/springframework/security/authentication/UserDetailsRepositoryAuthenticationManager.java

@@ -18,9 +18,12 @@
 
 package org.springframework.security.authentication;
 
+import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
 import org.springframework.security.core.Authentication;
 
 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 reactor.core.publisher.Mono;
 
@@ -31,6 +34,8 @@ import reactor.core.publisher.Mono;
 public class UserDetailsRepositoryAuthenticationManager implements ReactiveAuthenticationManager {
 	private final UserDetailsRepository repository;
 
+	private PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
+
 	public UserDetailsRepositoryAuthenticationManager(UserDetailsRepository userDetailsRepository) {
 		Assert.notNull(userDetailsRepository, "userDetailsRepository cannot be null");
 		this.repository = userDetailsRepository;
@@ -41,8 +46,13 @@ public class UserDetailsRepositoryAuthenticationManager implements ReactiveAuthe
 		final String username = authentication.getName();
 		return repository
 				.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")) )
 				.map( u -> new UsernamePasswordAuthenticationToken(u, u.getPassword(), u.getAuthorities()) );
 	}
+
+	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+		Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
+		this.passwordEncoder = passwordEncoder;
+	}
 }

+ 35 - 0
core/src/test/java/org/springframework/security/authentication/UserDetailsRepositoryAuthenticationManagerTests.java

@@ -16,6 +16,7 @@
 package org.springframework.security.authentication;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.when;
 
 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.UserDetailsRepository;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
 
@@ -39,6 +41,8 @@ import reactor.test.StepVerifier;
 public class UserDetailsRepositoryAuthenticationManagerTests {
 	@Mock
 	UserDetailsRepository repository;
+	@Mock
+	PasswordEncoder passwordEncoder;
 	UserDetailsRepositoryAuthenticationManager manager;
 	String username;
 	String password;
@@ -94,4 +98,35 @@ public class UserDetailsRepositoryAuthenticationManagerTests {
 		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();
+	}
 }