Skip to content

Commit b713d30

Browse files
committed
Merge branch '0.4.x' into 1.0.x
Closes gh-1267
2 parents 04da012 + 2b3b5d2 commit b713d30

15 files changed

+69
-36
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationCodeAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ public Authentication convert(HttpServletRequest request) {
8484
!key.equals(OAuth2ParameterNames.CLIENT_ID) &&
8585
!key.equals(OAuth2ParameterNames.CODE) &&
8686
!key.equals(OAuth2ParameterNames.REDIRECT_URI)) {
87-
additionalParameters.put(key, value.get(0));
87+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
8888
}
8989
});
9090

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationCodeRequestAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -138,7 +138,7 @@ public Authentication convert(HttpServletRequest request) {
138138
!key.equals(OAuth2ParameterNames.REDIRECT_URI) &&
139139
!key.equals(OAuth2ParameterNames.SCOPE) &&
140140
!key.equals(OAuth2ParameterNames.STATE)) {
141-
additionalParameters.put(key, value.get(0));
141+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
142142
}
143143
});
144144

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationConsentAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -93,7 +93,7 @@ public Authentication convert(HttpServletRequest request) {
9393
if (!key.equals(OAuth2ParameterNames.CLIENT_ID) &&
9494
!key.equals(OAuth2ParameterNames.STATE) &&
9595
!key.equals(OAuth2ParameterNames.SCOPE)) {
96-
additionalParameters.put(key, value.get(0));
96+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
9797
}
9898
});
9999

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2ClientCredentialsAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ public Authentication convert(HttpServletRequest request) {
7979
parameters.forEach((key, value) -> {
8080
if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) &&
8181
!key.equals(OAuth2ParameterNames.SCOPE)) {
82-
additionalParameters.put(key, value.get(0));
82+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
8383
}
8484
});
8585

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2EndpointUtils.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -58,10 +58,15 @@ static Map<String, Object> getParametersIfMatchesAuthorizationCodeGrantRequest(H
5858
if (!matchesAuthorizationCodeGrantRequest(request)) {
5959
return Collections.emptyMap();
6060
}
61-
Map<String, Object> parameters = new HashMap<>(getParameters(request).toSingleValueMap());
61+
MultiValueMap<String, String> multiValueParameters = getParameters(request);
6262
for (String exclusion : exclusions) {
63-
parameters.remove(exclusion);
63+
multiValueParameters.remove(exclusion);
6464
}
65+
66+
Map<String, Object> parameters = new HashMap<>();
67+
multiValueParameters.forEach((key, value) ->
68+
parameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0])));
69+
6570
return parameters;
6671
}
6772

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2RefreshTokenAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -90,7 +90,7 @@ public Authentication convert(HttpServletRequest request) {
9090
if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) &&
9191
!key.equals(OAuth2ParameterNames.REFRESH_TOKEN) &&
9292
!key.equals(OAuth2ParameterNames.SCOPE)) {
93-
additionalParameters.put(key, value.get(0));
93+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
9494
}
9595
});
9696

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2TokenIntrospectionAuthenticationConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -69,7 +69,7 @@ public Authentication convert(HttpServletRequest request) {
6969
parameters.forEach((key, value) -> {
7070
if (!key.equals(OAuth2ParameterNames.TOKEN) &&
7171
!key.equals(OAuth2ParameterNames.TOKEN_TYPE_HINT)) {
72-
additionalParameters.put(key, value.get(0));
72+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
7373
}
7474
});
7575

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/PublicClientAuthenticationConverter.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
package org.springframework.security.oauth2.server.authorization.web.authentication;
1717

1818
import java.util.HashMap;
19+
import java.util.Map;
1920

2021
import jakarta.servlet.http.HttpServletRequest;
2122

@@ -68,7 +69,11 @@ public Authentication convert(HttpServletRequest request) {
6869

6970
parameters.remove(OAuth2ParameterNames.CLIENT_ID);
7071

72+
Map<String, Object> additionalParameters = new HashMap<>();
73+
parameters.forEach((key, value) ->
74+
additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0])));
75+
7176
return new OAuth2ClientAuthenticationToken(clientId, ClientAuthenticationMethod.NONE, null,
72-
new HashMap<>(parameters.toSingleValueMap()));
77+
additionalParameters);
7378
}
7479
}

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationEndpointFilterTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ public void doFilterWhenAuthorizationRequestAuthenticatedThenAuthorizationRespon
556556
.thenReturn(authorizationCodeRequestAuthenticationResult);
557557

558558
MockHttpServletRequest request = createAuthorizationRequest(registeredClient);
559+
request.addParameter("custom-param", "custom-value-1", "custom-value-2");
560+
559561
MockHttpServletResponse response = new MockHttpServletResponse();
560562
FilterChain filterChain = mock(FilterChain.class);
561563

@@ -570,6 +572,12 @@ public void doFilterWhenAuthorizationRequestAuthenticatedThenAuthorizationRespon
570572
.asInstanceOf(type(WebAuthenticationDetails.class))
571573
.extracting(WebAuthenticationDetails::getRemoteAddress)
572574
.isEqualTo(REMOTE_ADDRESS);
575+
576+
// Assert that multi-valued request parameters are preserved
577+
assertThat(authorizationCodeRequestAuthenticationCaptor.getValue().getAdditionalParameters())
578+
.extracting(params -> params.get("custom-param"))
579+
.asInstanceOf(type(String[].class))
580+
.isEqualTo(new String[] { "custom-value-1", "custom-value-2" });
573581
assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());
574582
assertThat(response.getRedirectedUrl()).isEqualTo(
575583
"https://example.com?param=encoded%20parameter%20value&code=code&state=client%20state");

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilterTests.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
1818
import java.time.Duration;
1919
import java.time.Instant;
2020
import java.util.Arrays;
21-
import java.util.Collections;
2221
import java.util.HashSet;
2322
import java.util.Map;
2423

@@ -242,10 +241,9 @@ public void doFilterWhenAuthorizationCodeTokenRequestThenAccessTokenResponse() t
242241
new HashSet<>(Arrays.asList("scope1", "scope2")));
243242
OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
244243
"refresh-token", Instant.now(), Instant.now().plus(Duration.ofDays(1)));
245-
Map<String, Object> additionalParameters = Collections.singletonMap("custom-param", "custom-value");
246244
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
247245
new OAuth2AccessTokenAuthenticationToken(
248-
registeredClient, clientPrincipal, accessToken, refreshToken, additionalParameters);
246+
registeredClient, clientPrincipal, accessToken, refreshToken);
249247

250248
when(this.authenticationManager.authenticate(any())).thenReturn(accessTokenAuthentication);
251249

@@ -273,7 +271,8 @@ public void doFilterWhenAuthorizationCodeTokenRequestThenAccessTokenResponse() t
273271
assertThat(authorizationCodeAuthentication.getRedirectUri()).isEqualTo(
274272
request.getParameter(OAuth2ParameterNames.REDIRECT_URI));
275273
assertThat(authorizationCodeAuthentication.getAdditionalParameters())
276-
.containsExactly(entry("custom-param-1", "custom-value-1"));
274+
.containsExactly(entry("custom-param-1", "custom-value-1"),
275+
entry("custom-param-2", new String[] { "custom-value-1", "custom-value-2" }));
277276
assertThat(authorizationCodeAuthentication.getDetails())
278277
.asInstanceOf(type(WebAuthenticationDetails.class))
279278
.extracting(WebAuthenticationDetails::getRemoteAddress)
@@ -291,7 +290,6 @@ public void doFilterWhenAuthorizationCodeTokenRequestThenAccessTokenResponse() t
291290
accessToken.getExpiresAt().minusSeconds(1), accessToken.getExpiresAt().plusSeconds(1));
292291
assertThat(accessTokenResult.getScopes()).isEqualTo(accessToken.getScopes());
293292
assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo(refreshToken.getTokenValue());
294-
assertThat(accessTokenResponse.getAdditionalParameters()).containsExactly(entry("custom-param", "custom-value"));
295293
}
296294

297295
@Test
@@ -340,7 +338,8 @@ public void doFilterWhenClientCredentialsTokenRequestThenAccessTokenResponse() t
340338
assertThat(clientCredentialsAuthentication.getPrincipal()).isEqualTo(clientPrincipal);
341339
assertThat(clientCredentialsAuthentication.getScopes()).isEqualTo(registeredClient.getScopes());
342340
assertThat(clientCredentialsAuthentication.getAdditionalParameters())
343-
.containsExactly(entry("custom-param-1", "custom-value-1"));
341+
.containsExactly(entry("custom-param-1", "custom-value-1"),
342+
entry("custom-param-2", new String[] { "custom-value-1", "custom-value-2" }));
344343
assertThat(clientCredentialsAuthentication.getDetails())
345344
.asInstanceOf(type(WebAuthenticationDetails.class))
346345
.extracting(WebAuthenticationDetails::getRemoteAddress)
@@ -430,7 +429,8 @@ public void doFilterWhenRefreshTokenRequestThenAccessTokenResponse() throws Exce
430429
assertThat(refreshTokenAuthenticationToken.getPrincipal()).isEqualTo(clientPrincipal);
431430
assertThat(refreshTokenAuthenticationToken.getScopes()).isEqualTo(registeredClient.getScopes());
432431
assertThat(refreshTokenAuthenticationToken.getAdditionalParameters())
433-
.containsExactly(entry("custom-param-1", "custom-value-1"));
432+
.containsExactly(entry("custom-param-1", "custom-value-1"),
433+
entry("custom-param-2", new String[] { "custom-value-1", "custom-value-2" }));
434434
assertThat(refreshTokenAuthenticationToken.getDetails())
435435
.asInstanceOf(type(WebAuthenticationDetails.class))
436436
.extracting(WebAuthenticationDetails::getRemoteAddress)
@@ -613,6 +613,7 @@ private static MockHttpServletRequest createAuthorizationCodeTokenRequest(Regist
613613
// The client does not need to send the client ID param, but we are resilient in case they do
614614
request.addParameter(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId());
615615
request.addParameter("custom-param-1", "custom-value-1");
616+
request.addParameter("custom-param-2", "custom-value-1", "custom-value-2");
616617

617618
return request;
618619
}
@@ -627,6 +628,7 @@ private static MockHttpServletRequest createClientCredentialsTokenRequest(Regist
627628
request.addParameter(OAuth2ParameterNames.SCOPE,
628629
StringUtils.collectionToDelimitedString(registeredClient.getScopes(), " "));
629630
request.addParameter("custom-param-1", "custom-value-1");
631+
request.addParameter("custom-param-2", "custom-value-1", "custom-value-2");
630632

631633
return request;
632634
}
@@ -642,6 +644,7 @@ private static MockHttpServletRequest createRefreshTokenTokenRequest(RegisteredC
642644
request.addParameter(OAuth2ParameterNames.SCOPE,
643645
StringUtils.collectionToDelimitedString(registeredClient.getScopes(), " "));
644646
request.addParameter("custom-param-1", "custom-value-1");
647+
request.addParameter("custom-param-2", "custom-value-1", "custom-value-2");
645648

646649
return request;
647650
}

0 commit comments

Comments
 (0)