Răsfoiți Sursa

Treat Map Method Parameter as Immutable

Closes gh-14802
Josh Cummings 1 an în urmă
părinte
comite
0af0751cfd

+ 10 - 8
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospector.java

@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
@@ -179,16 +180,17 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
 	}
 
 	private OAuth2AuthenticatedPrincipal convertClaimsSet(Map<String, Object> claims) {
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
+		Map<String, Object> converted = new LinkedHashMap<>(claims);
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
 			if (v instanceof String) {
 				return Collections.singletonList(v);
 			}
 			return v;
 		});
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, (k, v) -> v.toString());
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.EXP,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, (k, v) -> v.toString());
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.EXP,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.IAT,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.IAT,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
 		// RFC-7662 page 7 directs users to RFC-7519 for defining the values of these
 		// issuer fields.
@@ -208,11 +210,11 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
 		// may be awkward to debug, we do not want to manipulate this value. Previous
 		// versions of Spring Security
 		// would *only* allow valid URLs, which is not what we wish to achieve here.
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.ISS, (k, v) -> v.toString());
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.NBF,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.ISS, (k, v) -> v.toString());
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.NBF,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
 		Collection<GrantedAuthority> authorities = new ArrayList<>();
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.SCOPE, (k, v) -> {
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.SCOPE, (k, v) -> {
 			if (v instanceof String) {
 				Collection<String> scopes = Arrays.asList(((String) v).split(" "));
 				for (String scope : scopes) {
@@ -222,7 +224,7 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
 			}
 			return v;
 		});
-		return new OAuth2IntrospectionAuthenticatedPrincipal(claims, authorities);
+		return new OAuth2IntrospectionAuthenticatedPrincipal(converted, authorities);
 	}
 
 }

+ 10 - 8
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospector.java

@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import reactor.core.publisher.Mono;
@@ -136,16 +137,17 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
 	}
 
 	private OAuth2AuthenticatedPrincipal convertClaimsSet(Map<String, Object> claims) {
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
+		Map<String, Object> converted = new LinkedHashMap<>(claims);
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
 			if (v instanceof String) {
 				return Collections.singletonList(v);
 			}
 			return v;
 		});
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, (k, v) -> v.toString());
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.EXP,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.CLIENT_ID, (k, v) -> v.toString());
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.EXP,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.IAT,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.IAT,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
 		// RFC-7662 page 7 directs users to RFC-7519 for defining the values of these
 		// issuer fields.
@@ -165,11 +167,11 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
 		// may be awkward to debug, we do not want to manipulate this value. Previous
 		// versions of Spring Security
 		// would *only* allow valid URLs, which is not what we wish to achieve here.
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.ISS, (k, v) -> v.toString());
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.NBF,
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.ISS, (k, v) -> v.toString());
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.NBF,
 				(k, v) -> Instant.ofEpochSecond(((Number) v).longValue()));
 		Collection<GrantedAuthority> authorities = new ArrayList<>();
-		claims.computeIfPresent(OAuth2TokenIntrospectionClaimNames.SCOPE, (k, v) -> {
+		converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.SCOPE, (k, v) -> {
 			if (v instanceof String) {
 				Collection<String> scopes = Arrays.asList(((String) v).split(" "));
 				for (String scope : scopes) {
@@ -179,7 +181,7 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
 			}
 			return v;
 		});
-		return new OAuth2IntrospectionAuthenticatedPrincipal(claims, authorities);
+		return new OAuth2IntrospectionAuthenticatedPrincipal(converted, authorities);
 	}
 
 	private OAuth2IntrospectionException onError(Throwable ex) {