浏览代码

Exclude well-known ports in expanded redirect-uri

Fixes gh-4836
Joe Grandja 7 年之前
父节点
当前提交
c04b3b4114

+ 8 - 7
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationRequestRedirectFilter.java

@@ -164,21 +164,22 @@ public class OAuth2AuthorizationRequestRedirectFilter extends OncePerRequestFilt
 	}
 	}
 
 
 	private String expandRedirectUri(HttpServletRequest request, ClientRegistration clientRegistration) {
 	private String expandRedirectUri(HttpServletRequest request, ClientRegistration clientRegistration) {
-		Map<String, String> uriVariables = new HashMap<>();
-		uriVariables.put("scheme", request.getScheme());
-		uriVariables.put("serverName", request.getServerName());
-		uriVariables.put("serverPort", String.valueOf(request.getServerPort()));
-		uriVariables.put("contextPath", request.getContextPath());
-		uriVariables.put("registrationId", clientRegistration.getRegistrationId());
+		int port = request.getServerPort();
+		if (("http".equals(request.getScheme()) && port == 80) || ("https".equals(request.getScheme()) && port == 443)) {
+			port = -1;		// Removes the port in UriComponentsBuilder
+		}
 
 
 		String baseUrl = UriComponentsBuilder.newInstance()
 		String baseUrl = UriComponentsBuilder.newInstance()
 			.scheme(request.getScheme())
 			.scheme(request.getScheme())
 			.host(request.getServerName())
 			.host(request.getServerName())
-			.port(request.getServerPort())
+			.port(port)
 			.path(request.getContextPath())
 			.path(request.getContextPath())
 			.build()
 			.build()
 			.toUriString();
 			.toUriString();
+
+		Map<String, String> uriVariables = new HashMap<>();
 		uriVariables.put("baseUrl", baseUrl);
 		uriVariables.put("baseUrl", baseUrl);
+		uriVariables.put("registrationId", clientRegistration.getRegistrationId());
 
 
 		return UriComponentsBuilder.fromUriString(clientRegistration.getRedirectUriTemplate())
 		return UriComponentsBuilder.fromUriString(clientRegistration.getRedirectUriTemplate())
 			.buildAndExpand(uriVariables)
 			.buildAndExpand(uriVariables)

+ 43 - 5
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizationRequestRedirectFilterTests.java

@@ -150,7 +150,7 @@ public class OAuth2AuthorizationRequestRedirectFilterTests {
 
 
 		verifyZeroInteractions(filterChain);
 		verifyZeroInteractions(filterChain);
 
 
-		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=http://localhost:80/login/oauth2/code/registration-1");
+		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=http://localhost/login/oauth2/code/registration-1");
 	}
 	}
 
 
 	@Test
 	@Test
@@ -182,7 +182,7 @@ public class OAuth2AuthorizationRequestRedirectFilterTests {
 		assertThat(authorizationRequest.getClientId()).isEqualTo(
 		assertThat(authorizationRequest.getClientId()).isEqualTo(
 			this.registration2.getClientId());
 			this.registration2.getClientId());
 		assertThat(authorizationRequest.getRedirectUri()).isEqualTo(
 		assertThat(authorizationRequest.getRedirectUri()).isEqualTo(
-			"http://localhost:80/login/oauth2/code/registration-2");
+			"http://localhost/login/oauth2/code/registration-2");
 		assertThat(authorizationRequest.getScopes()).isEqualTo(
 		assertThat(authorizationRequest.getScopes()).isEqualTo(
 			this.registration2.getScopes());
 			this.registration2.getScopes());
 		assertThat(authorizationRequest.getState()).isNotNull();
 		assertThat(authorizationRequest.getState()).isNotNull();
@@ -203,7 +203,7 @@ public class OAuth2AuthorizationRequestRedirectFilterTests {
 
 
 		verifyZeroInteractions(filterChain);
 		verifyZeroInteractions(filterChain);
 
 
-		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=token&client_id=client-3&scope=openid%20profile%20email&state=.{15,}&redirect_uri=http://localhost:80/login/oauth2/implicit/registration-3");
+		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=token&client_id=client-3&scope=openid%20profile%20email&state=.{15,}&redirect_uri=http://localhost/login/oauth2/implicit/registration-3");
 	}
 	}
 
 
 	@Test
 	@Test
@@ -243,7 +243,7 @@ public class OAuth2AuthorizationRequestRedirectFilterTests {
 
 
 		verifyZeroInteractions(filterChain);
 		verifyZeroInteractions(filterChain);
 
 
-		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=http://localhost:80/login/oauth2/code/registration-1");
+		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=http://localhost/login/oauth2/code/registration-1");
 	}
 	}
 
 
 	@Test
 	@Test
@@ -268,6 +268,44 @@ public class OAuth2AuthorizationRequestRedirectFilterTests {
 		assertThat(authorizationRequest.getRedirectUri()).isNotEqualTo(
 		assertThat(authorizationRequest.getRedirectUri()).isNotEqualTo(
 			this.registration2.getRedirectUriTemplate());
 			this.registration2.getRedirectUriTemplate());
 		assertThat(authorizationRequest.getRedirectUri()).isEqualTo(
 		assertThat(authorizationRequest.getRedirectUri()).isEqualTo(
-			"http://localhost:80/login/oauth2/code/registration-2");
+			"http://localhost/login/oauth2/code/registration-2");
+	}
+
+	@Test
+	public void doFilterWhenAuthorizationRequestIncludesPort80ThenExpandedRedirectUriExcludesPort() throws Exception {
+		String requestUri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI +
+			"/" + this.registration1.getRegistrationId();
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
+		request.setScheme("http");
+		request.setServerName("example.com");
+		request.setServerPort(80);
+		request.setServletPath(requestUri);
+		MockHttpServletResponse response = new MockHttpServletResponse();
+		FilterChain filterChain = mock(FilterChain.class);
+
+		this.filter.doFilter(request, response, filterChain);
+
+		verifyZeroInteractions(filterChain);
+
+		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=http://example.com/login/oauth2/code/registration-1");
+	}
+
+	@Test
+	public void doFilterWhenAuthorizationRequestIncludesPort443ThenExpandedRedirectUriExcludesPort() throws Exception {
+		String requestUri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI +
+			"/" + this.registration1.getRegistrationId();
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
+		request.setScheme("https");
+		request.setServerName("example.com");
+		request.setServerPort(443);
+		request.setServletPath(requestUri);
+		MockHttpServletResponse response = new MockHttpServletResponse();
+		FilterChain filterChain = mock(FilterChain.class);
+
+		this.filter.doFilter(request, response, filterChain);
+
+		verifyZeroInteractions(filterChain);
+
+		assertThat(response.getRedirectedUrl()).matches("https://provider.com/oauth2/authorize\\?response_type=code&client_id=client-1&scope=user&state=.{15,}&redirect_uri=https://example.com/login/oauth2/code/registration-1");
 	}
 	}
 }
 }