From dd826e8b96c774b36d92096d73d5c0e79fed7fa7 Mon Sep 17 00:00:00 2001 From: Konrad Windszus Date: Mon, 19 Jan 2026 09:22:11 +0100 Subject: [PATCH] Fix preemptive proxy authentication in JDK Client --- .../aether/transport/jdk/JdkTransporter.java | 27 ++++++++++++------- src/site/markdown/configuration.md | 4 +-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java index f5b2b29a4c..e1df36484f 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java +++ b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java @@ -162,6 +162,8 @@ final class JdkTransporter extends AbstractTransporter implements HttpTransporte private PasswordAuthentication serverAuthentication; + private PasswordAuthentication proxyAuthentication; + JdkTransporter( RepositorySystemSession session, RemoteRepository repository, @@ -452,13 +454,19 @@ protected void implPut(PutTask task) throws Exception { } private void prepare(HttpRequest.Builder requestBuilder) { - if (serverAuthentication != null - && (preemptiveAuth - || (preemptivePutAuth && requestBuilder.build().method().equals("PUT")))) { - // https://stackoverflow.com/a/58612586 - requestBuilder.setHeader( - "Authorization", - getBasicAuthValue(serverAuthentication.getUserName(), serverAuthentication.getPassword())); + if (preemptiveAuth + || (preemptivePutAuth && requestBuilder.build().method().equals("PUT"))) { + if (serverAuthentication != null) { + // https://stackoverflow.com/a/58612586 + requestBuilder.setHeader( + "Authorization", + getBasicAuthValue(serverAuthentication.getUserName(), serverAuthentication.getPassword())); + } + if (proxyAuthentication != null) { + requestBuilder.setHeader( + "Proxy-Authorization", + getBasicAuthValue(proxyAuthentication.getUserName(), proxyAuthentication.getPassword())); + } } } @@ -575,9 +583,8 @@ public X509Certificate[] getAcceptedIssuers() { String username = proxyAuthContext.get(AuthenticationContext.USERNAME); String password = proxyAuthContext.get(AuthenticationContext.PASSWORD); - authentications.put( - Authenticator.RequestorType.PROXY, - new PasswordAuthentication(username, password.toCharArray())); + proxyAuthentication = new PasswordAuthentication(username, password.toCharArray()); + authentications.put(Authenticator.RequestorType.PROXY, proxyAuthentication); } } } diff --git a/src/site/markdown/configuration.md b/src/site/markdown/configuration.md index 2e088bd0e0..d922c48119 100644 --- a/src/site/markdown/configuration.md +++ b/src/site/markdown/configuration.md @@ -141,8 +141,8 @@ To modify this file, edit the template and regenerate. | `"aether.transport.http.headers"` | `java.util.Map` | The request headers to use for HTTP-based repository connectors. The headers are specified using a Map , mapping a header name to its value. Besides this general key, clients may also specify headers for a specific remote repository by appending the suffix .<repoId> to this key when storing the headers map. The repository-specific headers map is supposed to be complete, i.e. is not merged with the general headers map. | - | | Yes | Session Configuration | | `"aether.transport.http.localAddress"` | `String` | The local address (interface) to use with HTTP transport. Not all transport supports this option. | - | 2.0.0 | Yes | Session Configuration | | `"aether.transport.http.maxConnectionsPerRoute"` | `Integer` | The maximum concurrent connections per route HTTP client is allowed to use. | `50` | 1.9.8 | Yes | Session Configuration | -| `"aether.transport.http.preemptiveAuth"` | `Boolean` | Should HTTP client use preemptive-authentication for all HTTP verbs (works only w/ BASIC). By default, is disabled, as it is considered less secure. | `false` | 1.9.6 | Yes | Session Configuration | -| `"aether.transport.http.preemptivePutAuth"` | `Boolean` | Boolean flag should the HTTP transport use preemptive-auth for PUT requests. Not all transport support this option. | `true` | 2.0.0 (moved out from maven-resolver-transport-http). | Yes | Session Configuration | +| `"aether.transport.http.preemptiveAuth"` | `Boolean` | Should HTTP client use preemptive-authentication for all HTTP verbs (works only w/ BASIC). By default, is disabled, as it is considered less secure. This affects both proxy and regular server authentication. | `false` | 1.9.6 | Yes | Session Configuration | +| `"aether.transport.http.preemptivePutAuth"` | `Boolean` | Boolean flag should the HTTP transport use preemptive-auth for PUT requests. Not all transport support this option. This affects both proxy and regular server authentication. | `true` | 2.0.0 (moved out from maven-resolver-transport-http). | Yes | Session Configuration | | `"aether.transport.http.requestTimeout"` | `Integer` | The maximum amount of time (in milliseconds) to wait for remaining data to arrive from a remote server. Note that this timeout does not restrict the overall duration of a request, it only restricts the duration of inactivity between consecutive data packets. Non-positive values indicate no timeout. | `1800000` | | Yes | Session Configuration | | `"aether.transport.http.retryHandler.count"` | `Integer` | The maximum number of times a request to a remote server should be retried in case of an error. | `3` | 1.9.6 | Yes | Session Configuration | | `"aether.transport.http.retryHandler.interval"` | `Long` | The initial retry interval in millis of request to a remote server should be waited in case of "too many requests" (HTTP codes 429 and 503). Accepts long as milliseconds. This value is used if remote server does not use Retry-After header, in which case Server value is obeyed. | `5000l` | 1.9.16 | Yes | Session Configuration |