Skip to content

Commit 24dbc5d

Browse files
chenzhenjiasjohnr
authored andcommitted
Fix array values of additionalParameters
Closes gh-15468
1 parent c1a303b commit 24dbc5d

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequest.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
import java.util.Collections;
2424
import java.util.LinkedHashMap;
2525
import java.util.LinkedHashSet;
26+
import java.util.List;
2627
import java.util.Map;
2728
import java.util.Set;
2829
import java.util.function.Consumer;
2930
import java.util.function.Function;
30-
31+
import java.util.stream.Stream;
32+
import java.util.stream.StreamSupport;
3133
import org.springframework.security.core.SpringSecurityCoreVersion;
3234
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3335
import org.springframework.util.Assert;
@@ -440,7 +442,13 @@ private String buildAuthorizationRequestUri() {
440442
Map<String, Object> parameters = getParameters(); // Not encoded
441443
this.parametersConsumer.accept(parameters);
442444
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
443-
parameters.forEach((k, v) -> queryParams.set(encodeQueryParam(k), encodeQueryParam(String.valueOf(v)))); // Encoded
445+
parameters.forEach((key1, value) -> {
446+
String key = encodeQueryParam(key1);
447+
List<String> values = queryValues(value)
448+
.map(o -> encodeQueryParam(String.valueOf(o)))
449+
.toList();
450+
queryParams.put(key, values);
451+
});
444452
UriBuilder uriBuilder = this.uriBuilderFactory.uriString(this.authorizationUri).queryParams(queryParams);
445453
return this.authorizationRequestUriFunction.apply(uriBuilder).toString();
446454
}
@@ -467,6 +475,20 @@ private static String encodeQueryParam(String value) {
467475
return UriUtils.encodeQueryParam(value, StandardCharsets.UTF_8);
468476
}
469477

478+
// Query value as a stream
479+
// If the value is an Iterable or an array it will be converted to a stream
480+
private static Stream<?> queryValues(Object value) {
481+
if (value instanceof Iterable) {
482+
return StreamSupport.stream(((Iterable<?>) value).spliterator(), false);
483+
484+
} else if (value.getClass().isArray()) {
485+
return Arrays.stream((Object[]) value);
486+
487+
} else {
488+
return Stream.of(value);
489+
}
490+
}
491+
470492
}
471493

472494
}

oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequestTests.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,18 @@
1616

1717
package org.springframework.security.oauth2.core.endpoint;
1818

19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
21+
1922
import java.net.URI;
2023
import java.util.Arrays;
2124
import java.util.HashMap;
2225
import java.util.LinkedHashSet;
2326
import java.util.Map;
2427
import java.util.Set;
25-
2628
import org.junit.jupiter.api.Test;
27-
2829
import org.springframework.security.oauth2.core.AuthorizationGrantType;
2930

30-
import static org.assertj.core.api.Assertions.assertThat;
31-
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
32-
3331
/**
3432
* Tests for {@link OAuth2AuthorizationRequest}.
3533
*
@@ -319,4 +317,19 @@ public void buildWhenNonAsciiAdditionalParametersThenProperlyEncoded() {
319317
+ "item%20amount=19.95%E2%82%AC&%C3%A2ge=4%C2%BD&item%20name=H%C3%85M%C3%96");
320318
}
321319

320+
@Test
321+
public void additionalParametersArrayValueOrIterableEncoded() {
322+
Map<String, Object> additionalParameters = new HashMap<>();
323+
additionalParameters.put("item", new String[] { "1", "2" });
324+
additionalParameters.put("item2", Arrays.asList("H" + '\u00c5' + "M" + '\u00d6', "H" + '\u00c5' + "M" + '\u00d6'));
325+
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
326+
.additionalParameters(additionalParameters)
327+
.build();
328+
assertThat(authorizationRequest.getAuthorizationRequestUri()).isNotNull();
329+
assertThat(authorizationRequest.getAuthorizationRequestUri()).isEqualTo(
330+
"https://example.com/login/oauth/authorize?" + "response_type=code&client_id=client-id&state=state&"
331+
+ "redirect_uri=https://example.com/authorize/oauth2/code/registration-id&"
332+
+ "item=1&item=2&item2=H%C3%85M%C3%96&item2=H%C3%85M%C3%96");
333+
}
334+
322335
}

0 commit comments

Comments
 (0)