Browse Source

Merge branch '1.0.x'

pull/1152/head
Joe Grandja 3 years ago
parent
commit
2a69bcfeeb
  1. 26
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationValidator.java
  2. 21
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProviderTests.java

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

@ -1,5 +1,5 @@ @@ -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");
* you may not use this file except in compliance with the License.
@ -100,23 +100,8 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme @@ -100,23 +100,8 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme
authorizationCodeRequestAuthentication, registeredClient);
}
String requestedRedirectHost = requestedRedirect.getHost();
if (requestedRedirectHost == null || requestedRedirectHost.equals("localhost")) {
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7.1
// While redirect URIs using localhost (i.e., "http://localhost:{port}/{path}")
// function similarly to loopback IP redirects described in Section 10.3.3,
// the use of "localhost" is NOT RECOMMENDED.
OAuth2Error error = new OAuth2Error(
OAuth2ErrorCodes.INVALID_REQUEST,
"localhost is not allowed for the redirect_uri (" + requestedRedirectUri + "). " +
"Use the IP literal (127.0.0.1) instead.",
"https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7.1");
throwError(error, OAuth2ParameterNames.REDIRECT_URI,
authorizationCodeRequestAuthentication, registeredClient);
}
if (!isLoopbackAddress(requestedRedirectHost)) {
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-9.7
if (!isLoopbackAddress(requestedRedirect.getHost())) {
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-22#section-4.1.3
// When comparing client redirect URIs against pre-registered URIs,
// authorization servers MUST utilize exact string matching.
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
@ -124,7 +109,7 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme @@ -124,7 +109,7 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme
authorizationCodeRequestAuthentication, registeredClient);
}
} else {
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-10.3.3
// As per https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08#section-8.4.2
// The authorization server MUST allow any port to be specified at the
// time of the request for loopback IP redirect URIs, to accommodate
// clients that obtain an available ephemeral port from the operating
@ -157,6 +142,9 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme @@ -157,6 +142,9 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationValidator impleme
}
private static boolean isLoopbackAddress(String host) {
if (!StringUtils.hasText(host)) {
return false;
}
// IPv6 loopback address should either be "0:0:0:0:0:0:0:1" or "::1"
if ("[0:0:0:0:0:0:0:1]".equals(host) || "[::1]".equals(host)) {
return true;

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

@ -181,27 +181,6 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests { @@ -181,27 +181,6 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
);
}
// gh-243
@Test
public void authenticateWhenRedirectUriLocalhostThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
.thenReturn(registeredClient);
OAuth2AuthorizationCodeRequestAuthenticationToken authentication =
new OAuth2AuthorizationCodeRequestAuthenticationToken(
AUTHORIZATION_URI, registeredClient.getClientId(), principal,
"https://localhost:5000", STATE, registeredClient.getScopes(), null);
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
.isInstanceOf(OAuth2AuthorizationCodeRequestAuthenticationException.class)
.satisfies(ex ->
assertAuthenticationException((OAuth2AuthorizationCodeRequestAuthenticationException) ex,
OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI, null)
)
.extracting(ex -> ((OAuth2AuthorizationCodeRequestAuthenticationException) ex).getError())
.satisfies(error ->
assertThat(error.getDescription()).isEqualTo("localhost is not allowed for the redirect_uri (https://localhost:5000). Use the IP literal (127.0.0.1) instead."));
}
@Test
public void authenticateWhenUnregisteredRedirectUriThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();

Loading…
Cancel
Save