|
1 | 1 | /*
|
2 |
| - * Copyright 2020-2022 the original author or authors. |
| 2 | + * Copyright 2020-2023 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -100,31 +100,16 @@ private static void validateRedirectUri(OAuth2AuthorizationCodeRequestAuthentica
|
100 | 100 | authorizationCodeRequestAuthentication, registeredClient);
|
101 | 101 | }
|
102 | 102 |
|
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 |
120 | 105 | // When comparing client redirect URIs against pre-registered URIs,
|
121 | 106 | // authorization servers MUST utilize exact string matching.
|
122 | 107 | if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
|
123 | 108 | throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI,
|
124 | 109 | authorizationCodeRequestAuthentication, registeredClient);
|
125 | 110 | }
|
126 | 111 | } 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 |
128 | 113 | // The authorization server MUST allow any port to be specified at the
|
129 | 114 | // time of the request for loopback IP redirect URIs, to accommodate
|
130 | 115 | // clients that obtain an available ephemeral port from the operating
|
@@ -157,6 +142,9 @@ private static void validateRedirectUri(OAuth2AuthorizationCodeRequestAuthentica
|
157 | 142 | }
|
158 | 143 |
|
159 | 144 | private static boolean isLoopbackAddress(String host) {
|
| 145 | + if (!StringUtils.hasText(host)) { |
| 146 | + return false; |
| 147 | + } |
160 | 148 | // IPv6 loopback address should either be "0:0:0:0:0:0:0:1" or "::1"
|
161 | 149 | if ("[0:0:0:0:0:0:0:1]".equals(host) || "[::1]".equals(host)) {
|
162 | 150 | return true;
|
|
0 commit comments