Эх сурвалжийг харах

Preserve encoding for authorization request redirect_uri parameter

Closes gh-1011
Andreas Fleig 2 жил өмнө
parent
commit
26205a2d8d

+ 13 - 4
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationEndpointFilter.java

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2020-2022 the original author or authors.
+ * Copyright 2020-2023 the original author or authors.
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
@@ -66,6 +66,9 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+import org.springframework.web.util.UriBuilder;
+import org.springframework.web.util.UriBuilderFactory;
 import org.springframework.web.util.UriComponentsBuilder;
 import org.springframework.web.util.UriComponentsBuilder;
 
 
 /**
 /**
@@ -296,8 +299,8 @@ public final class OAuth2AuthorizationEndpointFilter extends OncePerRequestFilte
 
 
 		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
 		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
 				(OAuth2AuthorizationCodeRequestAuthenticationToken) authentication;
 				(OAuth2AuthorizationCodeRequestAuthenticationToken) authentication;
-		UriComponentsBuilder uriBuilder = UriComponentsBuilder
-				.fromUriString(authorizationCodeRequestAuthentication.getRedirectUri())
+		UriBuilder uriBuilder = valuesOnlyEncodingUriBuilderFactory()
+				.uriString(authorizationCodeRequestAuthentication.getRedirectUri())
 				.queryParam(OAuth2ParameterNames.CODE, authorizationCodeRequestAuthentication.getAuthorizationCode().getTokenValue());
 				.queryParam(OAuth2ParameterNames.CODE, authorizationCodeRequestAuthentication.getAuthorizationCode().getTokenValue());
 		String redirectUri;
 		String redirectUri;
 		if (StringUtils.hasText(authorizationCodeRequestAuthentication.getState())) {
 		if (StringUtils.hasText(authorizationCodeRequestAuthentication.getState())) {
@@ -306,7 +309,7 @@ public final class OAuth2AuthorizationEndpointFilter extends OncePerRequestFilte
 			queryParams.put(OAuth2ParameterNames.STATE, authorizationCodeRequestAuthentication.getState());
 			queryParams.put(OAuth2ParameterNames.STATE, authorizationCodeRequestAuthentication.getState());
 			redirectUri = uriBuilder.build(queryParams).toString();
 			redirectUri = uriBuilder.build(queryParams).toString();
 		} else {
 		} else {
-			redirectUri = uriBuilder.toUriString();
+			redirectUri = uriBuilder.build().toString();
 		}
 		}
 		this.redirectStrategy.sendRedirect(request, response, redirectUri);
 		this.redirectStrategy.sendRedirect(request, response, redirectUri);
 	}
 	}
@@ -351,6 +354,12 @@ public final class OAuth2AuthorizationEndpointFilter extends OncePerRequestFilte
 		this.redirectStrategy.sendRedirect(request, response, redirectUri);
 		this.redirectStrategy.sendRedirect(request, response, redirectUri);
 	}
 	}
 
 
+	private UriBuilderFactory valuesOnlyEncodingUriBuilderFactory() {
+		DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
+		uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
+		return uriBuilderFactory;
+	}
+
 	/**
 	/**
 	 * For internal use only.
 	 * For internal use only.
 	 */
 	 */

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

@@ -537,7 +537,12 @@ public class OAuth2AuthorizationEndpointFilterTests {
 
 
 	@Test
 	@Test
 	public void doFilterWhenAuthorizationRequestAuthenticatedThenAuthorizationResponse() throws Exception {
 	public void doFilterWhenAuthorizationRequestAuthenticatedThenAuthorizationResponse() throws Exception {
-		RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
+		RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
+				.redirectUris(redirectUris -> {
+					redirectUris.clear();
+					redirectUris.add("https://example.com?param=encoded%20parameter%20value");
+				})
+				.build();
 		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthenticationResult =
 		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthenticationResult =
 				new OAuth2AuthorizationCodeRequestAuthenticationToken(
 				new OAuth2AuthorizationCodeRequestAuthenticationToken(
 						AUTHORIZATION_URI, registeredClient.getClientId(), principal, this.authorizationCode,
 						AUTHORIZATION_URI, registeredClient.getClientId(), principal, this.authorizationCode,
@@ -563,7 +568,7 @@ public class OAuth2AuthorizationEndpointFilterTests {
 				.isEqualTo(REMOTE_ADDRESS);
 				.isEqualTo(REMOTE_ADDRESS);
 		assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());
 		assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());
 		assertThat(response.getRedirectedUrl()).isEqualTo(
 		assertThat(response.getRedirectedUrl()).isEqualTo(
-				request.getParameter(OAuth2ParameterNames.REDIRECT_URI) + "?code=code&state=state");
+				"https://example.com?param=encoded%20parameter%20value&code=code&state=state");
 	}
 	}
 
 
 	@Test
 	@Test