Skip to content

Commit 8a79102

Browse files
chenzhenjiasjohnr
authored andcommitted
Fix array values of additionalParameters
Closes gh-15468
1 parent 0a4eb0f commit 8a79102

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;
@@ -463,7 +465,13 @@ private String buildAuthorizationRequestUri() {
463465
Map<String, Object> parameters = getParameters(); // Not encoded
464466
this.parametersConsumer.accept(parameters);
465467
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
466-
parameters.forEach((k, v) -> queryParams.set(encodeQueryParam(k), encodeQueryParam(String.valueOf(v)))); // Encoded
468+
parameters.forEach((key1, value) -> {
469+
String key = encodeQueryParam(key1);
470+
List<String> values = queryValues(value)
471+
.map(o -> encodeQueryParam(String.valueOf(o)))
472+
.toList();
473+
queryParams.put(key, values);
474+
});
467475
UriBuilder uriBuilder = this.uriBuilderFactory.uriString(this.authorizationUri).queryParams(queryParams);
468476
return this.authorizationRequestUriFunction.apply(uriBuilder).toString();
469477
}
@@ -490,6 +498,20 @@ private static String encodeQueryParam(String value) {
490498
return UriUtils.encodeQueryParam(value, StandardCharsets.UTF_8);
491499
}
492500

501+
// Query value as a stream
502+
// If the value is an Iterable or an array it will be converted to a stream
503+
private static Stream<?> queryValues(Object value) {
504+
if (value instanceof Iterable) {
505+
return StreamSupport.stream(((Iterable<?>) value).spliterator(), false);
506+
507+
} else if (value.getClass().isArray()) {
508+
return Arrays.stream((Object[]) value);
509+
510+
} else {
511+
return Stream.of(value);
512+
}
513+
}
514+
493515
}
494516

495517
}

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
*
@@ -364,4 +362,19 @@ public void buildWhenNonAsciiAdditionalParametersThenProperlyEncoded() {
364362
+ "item%20amount=19.95%E2%82%AC&%C3%A2ge=4%C2%BD&item%20name=H%C3%85M%C3%96");
365363
}
366364

365+
@Test
366+
public void additionalParametersArrayValueOrIterableEncoded() {
367+
Map<String, Object> additionalParameters = new HashMap<>();
368+
additionalParameters.put("item", new String[] { "1", "2" });
369+
additionalParameters.put("item2", Arrays.asList("H" + '\u00c5' + "M" + '\u00d6', "H" + '\u00c5' + "M" + '\u00d6'));
370+
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
371+
.additionalParameters(additionalParameters)
372+
.build();
373+
assertThat(authorizationRequest.getAuthorizationRequestUri()).isNotNull();
374+
assertThat(authorizationRequest.getAuthorizationRequestUri()).isEqualTo(
375+
"https://example.com/login/oauth/authorize?" + "response_type=code&client_id=client-id&state=state&"
376+
+ "redirect_uri=https://example.com/authorize/oauth2/code/registration-id&"
377+
+ "item=1&item=2&item2=H%C3%85M%C3%96&item2=H%C3%85M%C3%96");
378+
}
379+
367380
}

0 commit comments

Comments
 (0)