Skip to content

Commit 7ee7de6

Browse files
committed
Add grantedAuthorityMapper as a class member
- Add unit tests for setGrantedAuthorityMapper method Signed-off-by: dae won <[email protected]>
1 parent a427643 commit 7ee7de6

File tree

3 files changed

+71
-37
lines changed

3 files changed

+71
-37
lines changed

config/src/main/resources/org/springframework/security/config/spring-security-6.4.xsd

+28-28
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
</xs:annotation>
125125
<xs:complexType/>
126126
</xs:element>
127-
127+
128128
<xs:attributeGroup name="password-encoder.attlist">
129129
<xs:attribute name="ref" type="xs:token">
130130
<xs:annotation>
@@ -408,7 +408,7 @@
408408
</xs:annotation>
409409
</xs:attribute>
410410
</xs:attributeGroup>
411-
411+
412412
<xs:attributeGroup name="ldap-ap.attlist">
413413
<xs:attribute name="server-ref" type="xs:token">
414414
<xs:annotation>
@@ -488,7 +488,7 @@
488488
</xs:annotation>
489489
</xs:attribute>
490490
</xs:attributeGroup>
491-
491+
492492
<xs:attributeGroup name="password-compare.attlist">
493493
<xs:attribute name="password-attribute" type="xs:token">
494494
<xs:annotation>
@@ -554,7 +554,7 @@
554554
</xs:annotation>
555555
</xs:attribute>
556556
</xs:attributeGroup>
557-
557+
558558
<xs:attributeGroup name="protect.attlist">
559559
<xs:attribute name="method" use="required" type="xs:token">
560560
<xs:annotation>
@@ -892,13 +892,13 @@
892892
</xs:annotation>
893893
</xs:attribute>
894894
</xs:attributeGroup>
895-
896-
897-
898-
899-
900-
901-
895+
896+
897+
898+
899+
900+
901+
902902
<xs:attributeGroup name="protect-pointcut.attlist">
903903
<xs:attribute name="expression" use="required" type="xs:string">
904904
<xs:annotation>
@@ -1402,7 +1402,7 @@
14021402
</xs:annotation>
14031403
</xs:attribute>
14041404
</xs:attributeGroup>
1405-
1405+
14061406
<xs:attributeGroup name="access-denied-handler.attlist">
14071407
<xs:attribute name="ref" type="xs:token">
14081408
<xs:annotation>
@@ -1427,7 +1427,7 @@
14271427
</xs:annotation>
14281428
</xs:attribute>
14291429
</xs:attributeGroup>
1430-
1430+
14311431
<xs:attributeGroup name="intercept-url.attlist">
14321432
<xs:attribute name="pattern" type="xs:token">
14331433
<xs:annotation>
@@ -1484,7 +1484,7 @@
14841484
</xs:annotation>
14851485
</xs:attribute>
14861486
</xs:attributeGroup>
1487-
1487+
14881488
<xs:attributeGroup name="logout.attlist">
14891489
<xs:attribute name="logout-url" type="xs:token">
14901490
<xs:annotation>
@@ -1531,7 +1531,7 @@
15311531
<xs:attributeGroup ref="security:ref"/>
15321532
</xs:complexType>
15331533
</xs:element>
1534-
1534+
15351535
<xs:attributeGroup name="form-login.attlist">
15361536
<xs:attribute name="login-processing-url" type="xs:token">
15371537
<xs:annotation>
@@ -2064,7 +2064,7 @@
20642064
</xs:annotation>
20652065
</xs:attribute>
20662066
</xs:attributeGroup>
2067-
2067+
20682068
<xs:attributeGroup name="saml2-login.attlist">
20692069
<xs:attribute name="relying-party-registration-repository-ref" type="xs:token">
20702070
<xs:annotation>
@@ -2121,7 +2121,7 @@
21212121
</xs:annotation>
21222122
</xs:attribute>
21232123
</xs:attributeGroup>
2124-
2124+
21252125
<xs:attributeGroup name="saml2-logout.attlist">
21262126
<xs:attribute name="logout-url" type="xs:token">
21272127
<xs:annotation>
@@ -2583,7 +2583,7 @@
25832583
</xs:simpleType>
25842584
</xs:attribute>
25852585
</xs:attributeGroup>
2586-
2586+
25872587
<xs:attributeGroup name="http-basic.attlist">
25882588
<xs:attribute name="entry-point-ref" type="xs:token">
25892589
<xs:annotation>
@@ -2616,7 +2616,7 @@
26162616
</xs:annotation>
26172617
</xs:attribute>
26182618
</xs:attributeGroup>
2619-
2619+
26202620
<xs:attributeGroup name="session-management.attlist">
26212621
<xs:attribute name="authentication-strategy-explicit-invocation" type="xs:boolean">
26222622
<xs:annotation>
@@ -2679,7 +2679,7 @@
26792679
</xs:annotation>
26802680
</xs:attribute>
26812681
</xs:attributeGroup>
2682-
2682+
26832683
<xs:attributeGroup name="concurrency-control.attlist">
26842684
<xs:attribute name="max-sessions" type="xs:token">
26852685
<xs:annotation>
@@ -2726,7 +2726,7 @@
27262726
</xs:annotation>
27272727
</xs:attribute>
27282728
</xs:attributeGroup>
2729-
2729+
27302730
<xs:attributeGroup name="remember-me.attlist">
27312731
<xs:attribute name="key" type="xs:token">
27322732
<xs:annotation>
@@ -2824,7 +2824,7 @@
28242824
<xs:attributeGroup name="remember-me-data-source-ref">
28252825
<xs:attributeGroup ref="security:data-source-ref"/>
28262826
</xs:attributeGroup>
2827-
2827+
28282828
<xs:attributeGroup name="anonymous.attlist">
28292829
<xs:attribute name="key" type="xs:token">
28302830
<xs:annotation>
@@ -2857,8 +2857,8 @@
28572857
</xs:annotation>
28582858
</xs:attribute>
28592859
</xs:attributeGroup>
2860-
2861-
2860+
2861+
28622862
<xs:attributeGroup name="http-port">
28632863
<xs:attribute name="http" use="required" type="xs:token">
28642864
<xs:annotation>
@@ -2875,7 +2875,7 @@
28752875
</xs:annotation>
28762876
</xs:attribute>
28772877
</xs:attributeGroup>
2878-
2878+
28792879
<xs:attributeGroup name="x509.attlist">
28802880
<xs:attribute name="subject-principal-regex" type="xs:token">
28812881
<xs:annotation>
@@ -3018,7 +3018,7 @@
30183018
</xs:annotation>
30193019
</xs:attribute>
30203020
</xs:attributeGroup>
3021-
3021+
30223022
<xs:attributeGroup name="ap.attlist">
30233023
<xs:attribute name="ref" type="xs:token">
30243024
<xs:annotation>
@@ -3070,7 +3070,7 @@
30703070
</xs:annotation>
30713071
</xs:attribute>
30723072
</xs:attributeGroup>
3073-
3073+
30743074
<xs:attributeGroup name="user.attlist">
30753075
<xs:attribute name="name" use="required" type="xs:token">
30763076
<xs:annotation>
@@ -3819,4 +3819,4 @@
38193819
<xs:enumeration value="LAST"/>
38203820
</xs:restriction>
38213821
</xs:simpleType>
3822-
</xs:schema>
3822+
</xs:schema>

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

+20-3
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
159159

160160
private RowMapper<UserDetails> userDetailsMapper = this::mapToUser;
161161

162+
private RowMapper<GrantedAuthority> grantedAuthorityMapper = this::mapToGrantedAuthority;
163+
162164
public JdbcUserDetailsManager() {
163165
}
164166

@@ -182,6 +184,21 @@ public void setUserDetailsMapper(RowMapper<UserDetails> mapper) {
182184
this.userDetailsMapper = mapper;
183185
}
184186

187+
/**
188+
* Sets the {@code RowMapper} to convert each authority result row into a
189+
* {@link GrantedAuthority} object.
190+
*
191+
* The default mapper expects columns with names like 'authority' or 'role', and maps
192+
* them directly to SimpleGrantedAuthority objects.
193+
* @param mapper the {@code RowMapper} to use for mapping rows in the database to
194+
* GrantedAuthority objects, must not be null
195+
* @since 6.5
196+
*/
197+
public void setGrantedAuthorityMapper(RowMapper<GrantedAuthority> mapper) {
198+
Assert.notNull(mapper, "grantedAuthorityMapper cannot be null");
199+
this.grantedAuthorityMapper = mapper;
200+
}
201+
185202
@Override
186203
protected void initDao() throws ApplicationContextException {
187204
if (this.authenticationManager == null) {
@@ -197,7 +214,7 @@ protected void initDao() throws ApplicationContextException {
197214
*/
198215
@Override
199216
protected List<UserDetails> loadUsersByUsername(String username) {
200-
return getJdbcTemplate().query(getUsersByUsernameQuery(), userDetailsMapper, username);
217+
return getJdbcTemplate().query(getUsersByUsernameQuery(), this.userDetailsMapper, username);
201218
}
202219

203220
private UserDetails mapToUser(ResultSet rs, int rowNum) throws SQLException {
@@ -406,10 +423,10 @@ public List<GrantedAuthority> findGroupAuthorities(String groupName) {
406423
this.logger.debug("Loading authorities for group '" + groupName + "'");
407424
Assert.hasText(groupName, "groupName should have text");
408425
return getJdbcTemplate().query(this.groupAuthoritiesSql, new String[] { groupName },
409-
this::mapToGrantedAuthority);
426+
this.grantedAuthorityMapper);
410427
}
411428

412-
protected GrantedAuthority mapToGrantedAuthority(ResultSet rs, int rowNum) throws SQLException {
429+
private GrantedAuthority mapToGrantedAuthority(ResultSet rs, int rowNum) throws SQLException {
413430
String roleName = getRolePrefix() + rs.getString(3);
414431
return new SimpleGrantedAuthority(roleName);
415432
}

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

+23-6
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@
5252
import static org.mockito.ArgumentMatchers.any;
5353
import static org.mockito.ArgumentMatchers.anyInt;
5454
import static org.mockito.BDDMockito.given;
55-
import static org.mockito.Mockito.mock;
56-
import static org.mockito.Mockito.verify;
57-
import static org.mockito.Mockito.when;
55+
import static org.mockito.BDDMockito.mock;
56+
import static org.mockito.BDDMockito.verify;
5857

5958
/**
6059
* Tests for {@link JdbcUserDetailsManager}
@@ -373,21 +372,39 @@ public void createNewAuthenticationUsesNullPasswordToKeepPassordsSave() {
373372
@Test
374373
public void setUserDetailsMapperWithNullMapperThrowsException() {
375374
assertThatExceptionOfType(IllegalArgumentException.class)
376-
.isThrownBy(() -> this.manager.setUserDetailsMapper(null))
377-
.withMessage("userDetailsMapper cannot be null");
375+
.isThrownBy(() -> this.manager.setUserDetailsMapper(null))
376+
.withMessage("userDetailsMapper cannot be null");
378377
}
379378

380379
@Test
381380
public void setUserDetailsMapperWithMockMapper() throws SQLException {
382381
RowMapper<UserDetails> mockMapper = mock(RowMapper.class);
383-
when(mockMapper.mapRow(any(), anyInt())).thenReturn(joe);
382+
given(mockMapper.mapRow(any(), anyInt())).willReturn(joe);
384383
this.manager.setUserDetailsMapper(mockMapper);
385384
insertJoe();
386385
UserDetails newJoe = this.manager.loadUserByUsername("joe");
387386
assertThat(joe).isEqualTo(newJoe);
388387
verify(mockMapper).mapRow(any(), anyInt());
389388
}
390389

390+
@Test
391+
public void setGrantedAuthorityMapperWithNullMapperThrowsException() {
392+
assertThatExceptionOfType(IllegalArgumentException.class)
393+
.isThrownBy(() -> this.manager.setGrantedAuthorityMapper(null))
394+
.withMessage("grantedAuthorityMapper cannot be null");
395+
}
396+
397+
@Test
398+
public void setGrantedAuthorityMapperWithMockMapper() throws SQLException {
399+
RowMapper<GrantedAuthority> mockMapper = mock(RowMapper.class);
400+
GrantedAuthority mockAuthority = new SimpleGrantedAuthority("ROLE_MOCK");
401+
given(mockMapper.mapRow(any(), anyInt())).willReturn(mockAuthority);
402+
this.manager.setGrantedAuthorityMapper(mockMapper);
403+
List<GrantedAuthority> authGroup = this.manager.findGroupAuthorities("GROUP_0");
404+
assertThat(authGroup.get(0)).isEqualTo(mockAuthority);
405+
verify(mockMapper).mapRow(any(), anyInt());
406+
}
407+
391408
private Authentication authenticateJoe() {
392409
UsernamePasswordAuthenticationToken auth = UsernamePasswordAuthenticationToken.authenticated("joe", "password",
393410
joe.getAuthorities());

0 commit comments

Comments
 (0)