Skip to content

Commit fa7b44e

Browse files
committed
Merge branch '0.4.x' into 1.0.x
Closes gh-1150
2 parents 8f2251b + ef4c5d7 commit fa7b44e

File tree

2 files changed

+7
-40
lines changed

2 files changed

+7
-40
lines changed

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

Lines changed: 7 additions & 19 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.
@@ -100,31 +100,16 @@ private static void validateRedirectUri(OAuth2AuthorizationCodeRequestAuthentica
100100
authorizationCodeRequestAuthentication, registeredClient);
101101
}
102102

103-
String requestedRedirectHost = requestedRedirect.getHost();
104-
if (requestedRedirectHost == null || requestedRedirectHost.equals("localhost")) {
105-
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7.1
106-
// While redirect URIs using localhost (i.e., "http://localhost:{port}/{path}")
107-
// function similarly to loopback IP redirects described in Section 10.3.3,
108-
// the use of "localhost" is NOT RECOMMENDED.
109-
OAuth2Error error = new OAuth2Error(
110-
OAuth2ErrorCodes.INVALID_REQUEST,
111-
"localhost is not allowed for the redirect_uri (" + requestedRedirectUri + "). " +
112-
"Use the IP literal (127.0.0.1) instead.",
113-
"https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7.1");
114-
throwError(error, OAuth2ParameterNames.REDIRECT_URI,
115-
authorizationCodeRequestAuthentication, registeredClient);
116-
}
117-
118-
if (!isLoopbackAddress(requestedRedirectHost)) {
119-
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7
103+
if (!isLoopbackAddress(requestedRedirect.getHost())) {
104+
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-22#section-4.1.3
120105
// When comparing client redirect URIs against pre-registered URIs,
121106
// authorization servers MUST utilize exact string matching.
122107
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
123108
throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI,
124109
authorizationCodeRequestAuthentication, registeredClient);
125110
}
126111
} else {
127-
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-10.3.3
112+
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08#section-8.4.2
128113
// The authorization server MUST allow any port to be specified at the
129114
// time of the request for loopback IP redirect URIs, to accommodate
130115
// clients that obtain an available ephemeral port from the operating
@@ -157,6 +142,9 @@ private static void validateRedirectUri(OAuth2AuthorizationCodeRequestAuthentica
157142
}
158143

159144
private static boolean isLoopbackAddress(String host) {
145+
if (!StringUtils.hasText(host)) {
146+
return false;
147+
}
160148
// IPv6 loopback address should either be "0:0:0:0:0:0:0:1" or "::1"
161149
if ("[0:0:0:0:0:0:0:1]".equals(host) || "[::1]".equals(host)) {
162150
return true;

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -181,27 +181,6 @@ public void authenticateWhenInvalidRedirectUriFragmentThenThrowOAuth2Authorizati
181181
);
182182
}
183183

184-
// gh-243
185-
@Test
186-
public void authenticateWhenRedirectUriLocalhostThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() {
187-
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
188-
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
189-
.thenReturn(registeredClient);
190-
OAuth2AuthorizationCodeRequestAuthenticationToken authentication =
191-
new OAuth2AuthorizationCodeRequestAuthenticationToken(
192-
AUTHORIZATION_URI, registeredClient.getClientId(), principal,
193-
"https://localhost:5000", STATE, registeredClient.getScopes(), null);
194-
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
195-
.isInstanceOf(OAuth2AuthorizationCodeRequestAuthenticationException.class)
196-
.satisfies(ex ->
197-
assertAuthenticationException((OAuth2AuthorizationCodeRequestAuthenticationException) ex,
198-
OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI, null)
199-
)
200-
.extracting(ex -> ((OAuth2AuthorizationCodeRequestAuthenticationException) ex).getError())
201-
.satisfies(error ->
202-
assertThat(error.getDescription()).isEqualTo("localhost is not allowed for the redirect_uri (https://localhost:5000). Use the IP literal (127.0.0.1) instead."));
203-
}
204-
205184
@Test
206185
public void authenticateWhenUnregisteredRedirectUriThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() {
207186
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();

0 commit comments

Comments
 (0)