Skip to content

Commit 0a058c9

Browse files
andifalkjzheaux
authored andcommitted
Add setter for authorities claim name in JwtGrantedAuthoritiesConverter
Prior to this change authorities are always mapped using well known claim names ('scope' or 'scp'). To change this default behaviour the converter had to be replaced completely with a custom one. This commit adds an additional setter to configure a custom claim name like e.g. 'roles'. Without specifying a custom claim name the default claims to be used still remains to the well known ones. This way the authorities can be mapped according to customized token claims. Fixes gh-7100
1 parent 95caa47 commit 0a058c9

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverter.java

+19
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public final class JwtGrantedAuthoritiesConverter implements Converter<Jwt, Coll
4343

4444
private String authorityPrefix = DEFAULT_AUTHORITY_PREFIX;
4545

46+
private String authoritiesClaimName;
47+
4648
/**
4749
* Extract {@link GrantedAuthority}s from the given {@link Jwt}.
4850
*
@@ -70,7 +72,24 @@ public void setAuthorityPrefix(String authorityPrefix) {
7072
this.authorityPrefix = authorityPrefix;
7173
}
7274

75+
/**
76+
* Sets the name of token claim to use for mapping {@link GrantedAuthority authorities} by this converter.
77+
* Defaults to {@link JwtGrantedAuthoritiesConverter#WELL_KNOWN_AUTHORITIES_CLAIM_NAMES}.
78+
*
79+
* @param authoritiesClaimName The token claim name to map authorities
80+
* @since 5.2
81+
*/
82+
public void setAuthoritiesClaimName(String authoritiesClaimName) {
83+
Assert.hasText(authoritiesClaimName, "authoritiesClaimName cannot be empty");
84+
this.authoritiesClaimName = authoritiesClaimName;
85+
}
86+
7387
private String getAuthoritiesClaimName(Jwt jwt) {
88+
89+
if (this.authoritiesClaimName != null) {
90+
return this.authoritiesClaimName;
91+
}
92+
7493
for (String claimName : WELL_KNOWN_AUTHORITIES_CLAIM_NAMES) {
7594
if (jwt.containsClaim(claimName)) {
7695
return claimName;

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverterTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,49 @@ public void convertWhenTokenHasEmptyScopeAndNonEmptyScpThenScopeAttributeIsTrans
139139
assertThat(authorities).isEmpty();
140140
}
141141

142+
@Test
143+
public void convertWhenTokenHasCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToAuthorities() {
144+
Map<String, Object> claims = new HashMap<>();
145+
claims.put("roles", Arrays.asList("message:read", "message:write"));
146+
claims.put("scope", "missive:read missive:write");
147+
Jwt jwt = this.jwt(claims);
148+
149+
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
150+
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
151+
Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
152+
153+
assertThat(authorities).containsExactly(
154+
new SimpleGrantedAuthority("SCOPE_message:read"),
155+
new SimpleGrantedAuthority("SCOPE_message:write"));
156+
}
157+
158+
@Test
159+
public void convertWhenTokenHasEmptyCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToNoAuthorities() {
160+
Map<String, Object> claims = new HashMap<>();
161+
claims.put("roles", Collections.emptyList());
162+
claims.put("scope", "missive:read missive:write");
163+
Jwt jwt = this.jwt(claims);
164+
165+
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
166+
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
167+
Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
168+
169+
assertThat(authorities).isEmpty();
170+
}
171+
172+
@Test
173+
public void convertWhenTokenHasNoCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToNoAuthorities() {
174+
Map<String, Object> claims = new HashMap<>();
175+
claims.put("scope", "missive:read missive:write");
176+
Jwt jwt = this.jwt(claims);
177+
178+
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
179+
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
180+
Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
181+
182+
assertThat(authorities).isEmpty();
183+
}
184+
142185
private Jwt jwt(Map<String, Object> claims) {
143186
Map<String, Object> headers = new HashMap<>();
144187
headers.put("alg", JwsAlgorithms.RS256);

0 commit comments

Comments
 (0)