This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new 15d05606 [MRESOLVER-315] Preemptive auth (#256)
15d05606 is described below
commit 15d056063a0e335c3cea3c77ef7b4877599c29fa
Author: Tamas Cservenak <[email protected]>
AuthorDate: Wed Mar 1 08:36:02 2023 +0100
[MRESOLVER-315] Preemptive auth (#256)
Add option for HTTP preemptive auth.
---
https://issues.apache.org/jira/browse/MRESOLVER-315
---
.../eclipse/aether/ConfigurationProperties.java | 15 ++++++++++++
.../aether/transport/http/HttpTransporter.java | 11 +++++++++
.../aether/transport/http/HttpTransporterTest.java | 28 ++++++++++++++++++++++
src/site/markdown/configuration.md | 1 +
4 files changed, 55 insertions(+)
diff --git
a/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
index 7edecabe..5c9095ba 100644
---
a/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
+++
b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java
@@ -144,6 +144,21 @@ public final class ConfigurationProperties {
*/
public static final int DEFAULT_HTTP_RETRY_HANDLER_COUNT = 3;
+ /**
+ * Should HTTP client use preemptive auth (w/ BASIC) or not?
+ *
+ * @see #DEFAULT_HTTP_PREEMPTIVE_AUTH
+ * @since 1.9.6
+ */
+ public static final String HTTP_PREEMPTIVE_AUTH = PREFIX_CONNECTOR +
"http.preemptiveAuth";
+
+ /**
+ * The default value to use if {@link #HTTP_PREEMPTIVE_AUTH} isn't set
(false).
+ *
+ * @since 1.9.6
+ */
+ public static final boolean DEFAULT_HTTP_PREEMPTIVE_AUTH = false;
+
/**
* A flag indicating whether checksums which are retrieved during checksum
validation should be persisted in the
* local filesystem next to the file they provide the checksum for.
diff --git
a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
index 300f5b31..59bbfc07 100644
---
a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
+++
b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
@@ -61,6 +61,7 @@ import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.auth.BasicSchemeFactory;
import org.apache.http.impl.auth.DigestSchemeFactory;
import org.apache.http.impl.auth.KerberosSchemeFactory;
@@ -117,6 +118,8 @@ final class HttpTransporter extends AbstractTransporter {
private final LocalState state;
+ private final boolean preemptiveAuth;
+
HttpTransporter(
Map<String, ChecksumExtractor> checksumExtractors,
RemoteRepository repository,
@@ -151,6 +154,11 @@ final class HttpTransporter extends AbstractTransporter {
ConfigurationProperties.HTTP_HEADERS + "." +
repository.getId(),
ConfigurationProperties.HTTP_HEADERS);
+ this.preemptiveAuth = ConfigUtils.getBoolean(
+ session,
+ ConfigurationProperties.DEFAULT_HTTP_PREEMPTIVE_AUTH,
+ ConfigurationProperties.HTTP_PREEMPTIVE_AUTH + "." +
repository.getId(),
+ ConfigurationProperties.HTTP_PREEMPTIVE_AUTH);
String credentialEncoding = ConfigUtils.getString(
session,
ConfigurationProperties.DEFAULT_HTTP_CREDENTIAL_ENCODING,
@@ -348,6 +356,9 @@ final class HttpTransporter extends AbstractTransporter {
}
private void prepare(HttpUriRequest request, SharingHttpContext context) {
+ if (preemptiveAuth) {
+ state.setAuthScheme(server, new BasicScheme());
+ }
boolean put =
HttpPut.METHOD_NAME.equalsIgnoreCase(request.getMethod());
if (state.getWebDav() == null && (put || isPayloadPresent(request))) {
HttpOptions req = commonHeaders(new HttpOptions(request.getURI()));
diff --git
a/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
b/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
index a6557ed7..db00dc66 100644
---
a/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
+++
b/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
@@ -1036,6 +1036,34 @@ public class HttpTransporterTest {
assertNotNull(httpServer.getLogEntries().get(0).headers.get("Proxy-Authorization"));
}
+ @Test
+ public void testAuthSchemePreemptive() throws Exception {
+ httpServer.setAuthentication("testuser", "testpass");
+ session.setCache(new DefaultRepositoryCache());
+ auth = new AuthenticationBuilder()
+ .addUsername("testuser")
+ .addPassword("testpass")
+ .build();
+
+
session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_AUTH, false);
+ newTransporter(httpServer.getHttpUrl());
+ GetTask task = new GetTask(URI.create("repo/file.txt"));
+ transporter.get(task);
+ assertEquals("test", task.getDataString());
+ // there ARE challenge round-trips
+ assertEquals(2, httpServer.getLogEntries().size());
+
+ httpServer.getLogEntries().clear();
+
+
session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_AUTH, true);
+ newTransporter(httpServer.getHttpUrl());
+ task = new GetTask(URI.create("repo/file.txt"));
+ transporter.get(task);
+ assertEquals("test", task.getDataString());
+ // there are NO challenge round-trips, all goes through at first
+ assertEquals(1, httpServer.getLogEntries().size());
+ }
+
@Test
public void testConnectionReuse() throws Exception {
httpServer.addSslConnector();
diff --git a/src/site/markdown/configuration.md
b/src/site/markdown/configuration.md
index c752e290..649cc3c9 100644
--- a/src/site/markdown/configuration.md
+++ b/src/site/markdown/configuration.md
@@ -37,6 +37,7 @@ Option | Type | Description | Default Value | Supports Repo
ID Suffix
`aether.connector.http.cacheState` | boolean | Flag indicating whether a
memory-based cache is used for user tokens, connection managers, expect
continue requests and authentication schemes. | `true` | no
`aether.connector.http.credentialEncoding` | String | The encoding/charset to
use when exchanging credentials with HTTP servers. | `"ISO-8859-1"` | yes
`aether.connector.http.headers` | `Map<String, String>` | The request headers
to use for HTTP-based repository connectors. The headers are specified using a
map of strings mapping a header name to its value. The repository-specific
headers map is supposed to be complete, i.e. is not merged with the general
headers map. | - | yes
+`aether.connector.http.preemptiveAuth` | boolean | Should HTTP client use
preemptive-authentication (works only w/ BASIC) or not. | `false` | yes
`aether.connector.http.retryHandler.count` | int | The maximum number of times
a request to a remote HTTP server should be retried in case of an error. | `3`
| yes
`aether.connector.https.cipherSuites` | String | Comma-separated list of
[Cipher
Suites](https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites)
which are enabled for HTTPS connections. | - (no restriction) | no
`aether.connector.https.protocols` | String | Comma-separated list of
[Protocols](https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames)
which are enabled for HTTPS connections. | - (no restriction) | no