From f95a1f49dfeacee9f2563740e465a246dd2a664a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 22 Aug 2023 16:38:00 +0200 Subject: [PATCH] Polish "Add Basic Authorization for UrlResource" See gh-1822 --- .../springframework/core/io/UrlResource.java | 20 ++++++++++++------- .../core/io/ResourceTests.java | 14 +++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java index a8d66978c8..57685795e2 100644 --- a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java @@ -28,10 +28,10 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.Base64Utils; import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; @@ -42,12 +42,13 @@ import org.springframework.util.StringUtils; * * @author Juergen Hoeller * @author Sam Brannen - * @author Denis Kostin * @since 28.12.2003 * @see java.net.URL */ public class UrlResource extends AbstractFileResolvingResource { + private static final String AUTHORIZATION = "Authorization"; + /** * Original URI, if available; used for URI and File access. */ @@ -227,11 +228,6 @@ public class UrlResource extends AbstractFileResolvingResource { public InputStream getInputStream() throws IOException { URLConnection con = this.url.openConnection(); customizeConnection(con); - - if (this.url.getUserInfo() != null) { - String basicAuth = "Basic " + Base64Utils.encodeToString(url.getUserInfo().getBytes()); - con.setRequestProperty("Authorization", basicAuth); - } try { return con.getInputStream(); } @@ -244,6 +240,16 @@ public class UrlResource extends AbstractFileResolvingResource { } } + @Override + protected void customizeConnection(URLConnection con) throws IOException { + super.customizeConnection(con); + String userInfo = this.url.getUserInfo(); + if (userInfo != null) { + String encodedCredentials = Base64.getUrlEncoder().encodeToString(userInfo.getBytes()); + con.setRequestProperty(AUTHORIZATION, "Basic " + encodedCredentials); + } + } + /** * This implementation returns the underlying URL reference. */ diff --git a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java index 031fc7c7e4..bf3a246501 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java @@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Base64; import java.util.stream.Stream; import okhttp3.mockwebserver.Dispatcher; @@ -377,6 +378,19 @@ class ResourceTests { assertThat(request.getHeader("Framework-Name")).isEqualTo("Spring"); } + @Test + void useUserInfoToSetBasicAuth() throws Exception { + startServer(); + UrlResource resource = new UrlResource("http://alice:secret@localhost:" + + this.server.getPort() + "/resource"); + assertThat(resource.getInputStream()).hasContent("Spring"); + RecordedRequest request = this.server.takeRequest(); + String authorization = request.getHeader("Authorization"); + assertThat(authorization).isNotNull().startsWith("Basic "); + assertThat(new String(Base64.getDecoder().decode( + authorization.substring(6)), StandardCharsets.ISO_8859_1)).isEqualTo("alice:secret"); + } + @AfterEach void shutdown() throws Exception { this.server.shutdown();