Skip to content

Commit 0722c2d

Browse files
jhl221123rwinch
authored andcommitted
Implement UserDetailsPasswordService in JdbcUserDetailsManager
Signed-off-by: Junhyeok Lee <[email protected]>
1 parent 817938f commit 0722c2d

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

core/src/main/java/org/springframework/security/provisioning/JdbcUserDetailsManager.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.security.core.userdetails.User;
4747
import org.springframework.security.core.userdetails.UserCache;
4848
import org.springframework.security.core.userdetails.UserDetails;
49+
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
4950
import org.springframework.security.core.userdetails.cache.NullUserCache;
5051
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;
5152
import org.springframework.util.Assert;
@@ -65,7 +66,8 @@
6566
* @author Luke Taylor
6667
* @since 2.0
6768
*/
68-
public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsManager, GroupManager {
69+
public class JdbcUserDetailsManager extends JdbcDaoImpl
70+
implements UserDetailsManager, GroupManager, UserDetailsPasswordService {
6971

7072
public static final String DEF_CREATE_USER_SQL = "insert into users (username, password, enabled) values (?,?,?)";
7173

@@ -162,6 +164,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
162164

163165
private RowMapper<GrantedAuthority> grantedAuthorityMapper = this::mapToGrantedAuthority;
164166

167+
private boolean enableUpdatePassword = false;
168+
165169
public JdbcUserDetailsManager() {
166170
}
167171

@@ -591,6 +595,20 @@ public void setUserCache(UserCache userCache) {
591595
this.userCache = userCache;
592596
}
593597

598+
/**
599+
* Sets whether the {@link #updatePassword(UserDetails, String)} method should
600+
* actually update the password.
601+
* <p>
602+
* Defaults to {@code false} to prevent accidental password updates that might produce
603+
* passwords that are too large for the current database schema. Users must explicitly
604+
* set this to {@code true} to enable password updates.
605+
* @param enableUpdatePassword {@code true} to enable password updates, {@code false}
606+
* otherwise.
607+
*/
608+
public void setEnableUpdatePassword(boolean enableUpdatePassword) {
609+
this.enableUpdatePassword = enableUpdatePassword;
610+
}
611+
594612
private void validateUserDetails(UserDetails user) {
595613
Assert.hasText(user.getUsername(), "Username may not be empty or null");
596614
validateAuthorities(user.getAuthorities());
@@ -604,4 +622,14 @@ private void validateAuthorities(Collection<? extends GrantedAuthority> authorit
604622
}
605623
}
606624

625+
@Override
626+
public UserDetails updatePassword(UserDetails user, String newPassword) {
627+
if (this.enableUpdatePassword) {
628+
UserDetails updated = User.withUserDetails(user).password(newPassword).build();
629+
updateUser(updated);
630+
return updated;
631+
}
632+
return user;
633+
}
634+
607635
}

core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,23 @@ public void setGrantedAuthorityMapperWithMockMapper() throws SQLException {
410410
verify(mockMapper).mapRow(any(), anyInt());
411411
}
412412

413+
@Test
414+
void updatePasswordWhenDisabledReturnOriginalUser() {
415+
insertJoe();
416+
this.manager.updatePassword(joe, "new");
417+
UserDetails newJoe = this.manager.loadUserByUsername("joe");
418+
assertThat(newJoe.getPassword()).isEqualTo("password");
419+
}
420+
421+
@Test
422+
void updatePasswordWhenEnabledShouldUpdatePassword() {
423+
insertJoe();
424+
this.manager.setEnableUpdatePassword(true);
425+
this.manager.updatePassword(joe, "new");
426+
UserDetails newJoe = this.manager.loadUserByUsername("joe");
427+
assertThat(newJoe.getPassword()).isEqualTo("new");
428+
}
429+
413430
private Authentication authenticateJoe() {
414431
UsernamePasswordAuthenticationToken auth = UsernamePasswordAuthenticationToken.authenticated("joe", "password",
415432
joe.getAuthorities());

0 commit comments

Comments
 (0)