From 45b51fe3c879b5c67bef1ed6827d3fc02c30a23e Mon Sep 17 00:00:00 2001 From: dae won Date: Sat, 15 Feb 2025 23:59:36 +0900 Subject: [PATCH] Add grantedAuthorityMapper as a class member - Add unit tests for setGrantedAuthorityMapper method Signed-off-by: dae won --- .../provisioning/JdbcUserDetailsManager.java | 23 +++++++++++++-- .../JdbcUserDetailsManagerTests.java | 29 +++++++++++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/springframework/security/provisioning/JdbcUserDetailsManager.java b/core/src/main/java/org/springframework/security/provisioning/JdbcUserDetailsManager.java index b081bfef6c..291f15f322 100644 --- a/core/src/main/java/org/springframework/security/provisioning/JdbcUserDetailsManager.java +++ b/core/src/main/java/org/springframework/security/provisioning/JdbcUserDetailsManager.java @@ -159,6 +159,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa private RowMapper userDetailsMapper = this::mapToUser; + private RowMapper grantedAuthorityMapper = this::mapToGrantedAuthority; + public JdbcUserDetailsManager() { } @@ -182,6 +184,21 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa this.userDetailsMapper = mapper; } + /** + * Sets the {@code RowMapper} to convert each authority result row into a + * {@link GrantedAuthority} object. + * + * The default mapper expects columns with names like 'authority' or 'role', and maps + * them directly to SimpleGrantedAuthority objects. + * @param mapper the {@code RowMapper} to use for mapping rows in the database to + * GrantedAuthority objects, must not be null + * @since 6.5 + */ + public void setGrantedAuthorityMapper(RowMapper mapper) { + Assert.notNull(mapper, "grantedAuthorityMapper cannot be null"); + this.grantedAuthorityMapper = mapper; + } + @Override protected void initDao() throws ApplicationContextException { if (this.authenticationManager == null) { @@ -197,7 +214,7 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa */ @Override protected List loadUsersByUsername(String username) { - return getJdbcTemplate().query(getUsersByUsernameQuery(), userDetailsMapper, username); + return getJdbcTemplate().query(getUsersByUsernameQuery(), this.userDetailsMapper, username); } private UserDetails mapToUser(ResultSet rs, int rowNum) throws SQLException { @@ -406,10 +423,10 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa this.logger.debug("Loading authorities for group '" + groupName + "'"); Assert.hasText(groupName, "groupName should have text"); return getJdbcTemplate().query(this.groupAuthoritiesSql, new String[] { groupName }, - this::mapToGrantedAuthority); + this.grantedAuthorityMapper); } - protected GrantedAuthority mapToGrantedAuthority(ResultSet rs, int rowNum) throws SQLException { + private GrantedAuthority mapToGrantedAuthority(ResultSet rs, int rowNum) throws SQLException { String roleName = getRolePrefix() + rs.getString(3); return new SimpleGrantedAuthority(roleName); } diff --git a/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java b/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java index a13c8e388c..65b1d4b1c4 100644 --- a/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java +++ b/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java @@ -52,9 +52,8 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.mock; +import static org.mockito.BDDMockito.verify; /** * Tests for {@link JdbcUserDetailsManager} @@ -373,14 +372,14 @@ public class JdbcUserDetailsManagerTests { @Test public void setUserDetailsMapperWithNullMapperThrowsException() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> this.manager.setUserDetailsMapper(null)) - .withMessage("userDetailsMapper cannot be null"); + .isThrownBy(() -> this.manager.setUserDetailsMapper(null)) + .withMessage("userDetailsMapper cannot be null"); } @Test public void setUserDetailsMapperWithMockMapper() throws SQLException { RowMapper mockMapper = mock(RowMapper.class); - when(mockMapper.mapRow(any(), anyInt())).thenReturn(joe); + given(mockMapper.mapRow(any(), anyInt())).willReturn(joe); this.manager.setUserDetailsMapper(mockMapper); insertJoe(); UserDetails newJoe = this.manager.loadUserByUsername("joe"); @@ -388,6 +387,24 @@ public class JdbcUserDetailsManagerTests { verify(mockMapper).mapRow(any(), anyInt()); } + @Test + public void setGrantedAuthorityMapperWithNullMapperThrowsException() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> this.manager.setGrantedAuthorityMapper(null)) + .withMessage("grantedAuthorityMapper cannot be null"); + } + + @Test + public void setGrantedAuthorityMapperWithMockMapper() throws SQLException { + RowMapper mockMapper = mock(RowMapper.class); + GrantedAuthority mockAuthority = new SimpleGrantedAuthority("ROLE_MOCK"); + given(mockMapper.mapRow(any(), anyInt())).willReturn(mockAuthority); + this.manager.setGrantedAuthorityMapper(mockMapper); + List authGroup = this.manager.findGroupAuthorities("GROUP_0"); + assertThat(authGroup.get(0)).isEqualTo(mockAuthority); + verify(mockMapper).mapRow(any(), anyInt()); + } + private Authentication authenticateJoe() { UsernamePasswordAuthenticationToken auth = UsernamePasswordAuthenticationToken.authenticated("joe", "password", joe.getAuthorities());