|
17 | 17 | package org.springframework.security.authentication.dao;
|
18 | 18 |
|
19 | 19 | import static org.assertj.core.api.Assertions.assertThat;
|
| 20 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
20 | 21 | import static org.assertj.core.api.Assertions.fail;
|
| 22 | +import static org.mockito.ArgumentMatchers.any; |
| 23 | +import static org.mockito.ArgumentMatchers.eq; |
21 | 24 | import static org.mockito.Matchers.anyString;
|
22 | 25 | import static org.mockito.Matchers.isA;
|
23 | 26 | import static org.mockito.Mockito.mock;
|
24 | 27 | import static org.mockito.Mockito.times;
|
25 | 28 | import static org.mockito.Mockito.verify;
|
| 29 | +import static org.mockito.Mockito.verifyZeroInteractions; |
26 | 30 | import static org.mockito.Mockito.when;
|
27 | 31 |
|
28 | 32 | import java.security.SecureRandom;
|
|
43 | 47 | import org.springframework.security.core.Authentication;
|
44 | 48 | import org.springframework.security.core.GrantedAuthority;
|
45 | 49 | import org.springframework.security.core.authority.AuthorityUtils;
|
| 50 | +import org.springframework.security.core.userdetails.PasswordEncodedUser; |
46 | 51 | import org.springframework.security.core.userdetails.User;
|
47 | 52 | import org.springframework.security.core.userdetails.UserDetails;
|
48 | 53 | import org.springframework.security.core.userdetails.UserDetailsService;
|
|
53 | 58 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
54 | 59 | import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
55 | 60 | import org.springframework.security.crypto.password.PasswordEncoder;
|
| 61 | +import org.springframework.security.core.userdetails.UserDetailsPasswordService; |
56 | 62 |
|
57 | 63 | /**
|
58 | 64 | * Tests {@link DaoAuthenticationProvider}.
|
@@ -399,6 +405,80 @@ public void testAuthenticatesWithForcePrincipalAsString() {
|
399 | 405 | assertThat(castResult.getPrincipal()).isEqualTo("rod");
|
400 | 406 | }
|
401 | 407 |
|
| 408 | + @Test |
| 409 | + public void authenticateWhenSuccessAndPasswordManagerThenUpdates() { |
| 410 | + String password = "password"; |
| 411 | + String encodedPassword = "encoded"; |
| 412 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( |
| 413 | + "user", password); |
| 414 | + |
| 415 | + PasswordEncoder encoder = mock(PasswordEncoder.class); |
| 416 | + UserDetailsService userDetailsService = mock(UserDetailsService.class); |
| 417 | + UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); |
| 418 | + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); |
| 419 | + provider.setPasswordEncoder(encoder); |
| 420 | + provider.setUserDetailsService(userDetailsService); |
| 421 | + provider.setUserDetailsPasswordService(passwordManager); |
| 422 | + |
| 423 | + UserDetails user = PasswordEncodedUser.user(); |
| 424 | + when(encoder.matches(any(), any())).thenReturn(true); |
| 425 | + when(encoder.upgradeEncoding(any())).thenReturn(true); |
| 426 | + when(encoder.encode(any())).thenReturn(encodedPassword); |
| 427 | + when(userDetailsService.loadUserByUsername(any())).thenReturn(user); |
| 428 | + when(passwordManager.updatePassword(any(), any())).thenReturn(user); |
| 429 | + |
| 430 | + Authentication result = provider.authenticate(token); |
| 431 | + |
| 432 | + verify(encoder).encode(password); |
| 433 | + verify(passwordManager).updatePassword(eq(user), eq(encodedPassword)); |
| 434 | + } |
| 435 | + |
| 436 | + @Test |
| 437 | + public void authenticateWhenBadCredentialsAndPasswordManagerThenNoUpdate() { |
| 438 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( |
| 439 | + "user", "password"); |
| 440 | + |
| 441 | + PasswordEncoder encoder = mock(PasswordEncoder.class); |
| 442 | + UserDetailsService userDetailsService = mock(UserDetailsService.class); |
| 443 | + UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); |
| 444 | + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); |
| 445 | + provider.setPasswordEncoder(encoder); |
| 446 | + provider.setUserDetailsService(userDetailsService); |
| 447 | + provider.setUserDetailsPasswordService(passwordManager); |
| 448 | + |
| 449 | + UserDetails user = PasswordEncodedUser.user(); |
| 450 | + when(encoder.matches(any(), any())).thenReturn(false); |
| 451 | + when(userDetailsService.loadUserByUsername(any())).thenReturn(user); |
| 452 | + |
| 453 | + assertThatThrownBy(() -> provider.authenticate(token)) |
| 454 | + .isInstanceOf(BadCredentialsException.class); |
| 455 | + |
| 456 | + verifyZeroInteractions(passwordManager); |
| 457 | + } |
| 458 | + |
| 459 | + @Test |
| 460 | + public void authenticateWhenNotUpgradeAndPasswordManagerThenNoUpdate() { |
| 461 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( |
| 462 | + "user", "password"); |
| 463 | + |
| 464 | + PasswordEncoder encoder = mock(PasswordEncoder.class); |
| 465 | + UserDetailsService userDetailsService = mock(UserDetailsService.class); |
| 466 | + UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); |
| 467 | + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); |
| 468 | + provider.setPasswordEncoder(encoder); |
| 469 | + provider.setUserDetailsService(userDetailsService); |
| 470 | + provider.setUserDetailsPasswordService(passwordManager); |
| 471 | + |
| 472 | + UserDetails user = PasswordEncodedUser.user(); |
| 473 | + when(encoder.matches(any(), any())).thenReturn(true); |
| 474 | + when(encoder.upgradeEncoding(any())).thenReturn(false); |
| 475 | + when(userDetailsService.loadUserByUsername(any())).thenReturn(user); |
| 476 | + |
| 477 | + Authentication result = provider.authenticate(token); |
| 478 | + |
| 479 | + verifyZeroInteractions(passwordManager); |
| 480 | + } |
| 481 | + |
402 | 482 | @Test
|
403 | 483 | public void testDetectsNullBeingReturnedFromAuthenticationDao() {
|
404 | 484 | UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
|
|
0 commit comments