Browse Source

Polish JwtGrantedAuthoritiesConverter

Rework the implementation so that it is clearer that authorities are
derived from a single claim.

Issue: gh-6273
Josh Cummings 6 years ago
parent
commit
d843818e48

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

@@ -16,10 +16,10 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.stream.Collectors;
 
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.core.GrantedAuthority;
@@ -35,42 +35,51 @@ import org.springframework.util.StringUtils;
  * @since 5.2
  */
 public final class JwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
-	private static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_";
+	private static final String DEFAULT_AUTHORITY_PREFIX = "SCOPE_";
 
-	private static final Collection<String> WELL_KNOWN_SCOPE_ATTRIBUTE_NAMES =
+	private static final Collection<String> WELL_KNOWN_AUTHORITIES_CLAIM_NAMES =
 			Arrays.asList("scope", "scp");
 
 	/**
-	 * Extracts the authorities
+	 * Extract {@link GrantedAuthority}s from the given {@link Jwt}.
+	 *
 	 * @param jwt The {@link Jwt} token
 	 * @return The {@link GrantedAuthority authorities} read from the token scopes
 	 */
 	@Override
 	public Collection<GrantedAuthority> convert(Jwt jwt) {
-		return getScopes(jwt)
-				.stream()
-				.map(authority -> SCOPE_AUTHORITY_PREFIX + authority)
-				.map(SimpleGrantedAuthority::new)
-				.collect(Collectors.toList());
+		Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
+		for (String authority : getAuthorities(jwt)) {
+			grantedAuthorities.add(new SimpleGrantedAuthority(DEFAULT_AUTHORITY_PREFIX + authority));
+		}
+		return grantedAuthorities;
 	}
 
-	/**
-	 * Gets the scopes from a {@link Jwt} token
-	 * @param jwt The {@link Jwt} token
-	 * @return The scopes from the token
-	 */
-	private Collection<String> getScopes(Jwt jwt) {
-		for ( String attributeName : WELL_KNOWN_SCOPE_ATTRIBUTE_NAMES ) {
-			Object scopes = jwt.getClaims().get(attributeName);
-			if (scopes instanceof String) {
-				if (StringUtils.hasText((String) scopes)) {
-					return Arrays.asList(((String) scopes).split(" "));
-				} else {
-					return Collections.emptyList();
-				}
-			} else if (scopes instanceof Collection) {
-				return (Collection<String>) scopes;
+	private String getAuthoritiesClaimName(Jwt jwt) {
+		for (String claimName : WELL_KNOWN_AUTHORITIES_CLAIM_NAMES) {
+			if (jwt.containsClaim(claimName)) {
+				return claimName;
+			}
+		}
+		return null;
+	}
+
+	private Collection<String> getAuthorities(Jwt jwt) {
+		String claimName = getAuthoritiesClaimName(jwt);
+
+		if (claimName == null) {
+			return Collections.emptyList();
+		}
+
+		Object authorities = jwt.getClaim(claimName);
+		if (authorities instanceof String) {
+			if (StringUtils.hasText((String) authorities)) {
+				return Arrays.asList(((String) authorities).split(" "));
+			} else {
+				return Collections.emptyList();
 			}
+		} else if (authorities instanceof Collection) {
+			return (Collection<String>) authorities;
 		}
 
 		return Collections.emptyList();