Skip to content

Commit

Permalink
[MRESOLVER-341] Preemptive PUT auth (#265)
Browse files Browse the repository at this point in the history
As resolver faces many broken servers that
does expect broken behaviour to blindly do 
preemptive auth for PUT.

By default this is enabled to do same thing as Wagon did.

---

https://issues.apache.org/jira/browse/MRESOLVER-341
  • Loading branch information
cstamas authored Mar 7, 2023
1 parent 0a7d636 commit 28fec45
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ final class HttpTransporter extends AbstractTransporter {

static final String SUPPORT_WEBDAV = "aether.connector.http.supportWebDav";

static final String PREEMPTIVE_PUT_AUTH = "aether.connector.http.preemptivePutAuth";

private static final Pattern CONTENT_RANGE_PATTERN =
Pattern.compile("\\s*bytes\\s+([0-9]+)\\s*-\\s*([0-9]+)\\s*/.*");

Expand All @@ -122,6 +124,8 @@ final class HttpTransporter extends AbstractTransporter {

private final boolean preemptiveAuth;

private final boolean preemptivePutAuth;

private final boolean supportWebDav;

HttpTransporter(
Expand Down Expand Up @@ -168,7 +172,10 @@ final class HttpTransporter extends AbstractTransporter {
ConfigurationProperties.DEFAULT_HTTP_PREEMPTIVE_AUTH,
ConfigurationProperties.HTTP_PREEMPTIVE_AUTH + "." + repository.getId(),
ConfigurationProperties.HTTP_PREEMPTIVE_AUTH);
this.supportWebDav =
this.preemptivePutAuth = // defaults to true: Wagon does same
ConfigUtils.getBoolean(
session, true, PREEMPTIVE_PUT_AUTH + "." + repository.getId(), PREEMPTIVE_PUT_AUTH);
this.supportWebDav = // defaults to false: who needs it will enable it
ConfigUtils.getBoolean(session, false, SUPPORT_WEBDAV + "." + repository.getId(), SUPPORT_WEBDAV);
String credentialEncoding = ConfigUtils.getString(
session,
Expand Down Expand Up @@ -367,11 +374,11 @@ private void execute(HttpUriRequest request, EntityGetter getter) throws Excepti
}

private void prepare(HttpUriRequest request, SharingHttpContext context) {
if (preemptiveAuth) {
context.getAuthCache().put(server, new BasicScheme());

This comment has been minimized.

Copy link
@slawekjaranowski

slawekjaranowski Mar 7, 2023

Member

should be context.getAuthCache().put(... in other case key will be miss due to normalization

final boolean put = HttpPut.METHOD_NAME.equalsIgnoreCase(request.getMethod());
if (preemptiveAuth || (preemptivePutAuth && put)) {
state.setAuthScheme(server, new BasicScheme());
}
if (supportWebDav) {
boolean put = HttpPut.METHOD_NAME.equalsIgnoreCase(request.getMethod());
if (state.getWebDav() == null && (put || isPayloadPresent(request))) {
HttpOptions req = commonHeaders(new HttpOptions(request.getURI()));
try (CloseableHttpResponse response = client.execute(server, req, context)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -910,8 +910,22 @@ public void testGetPut_AuthCache() throws Exception {
assertEquals(1, listener.startedCount);
}

@Test
public void testPut_PreemptiveIsDefault() throws Exception {
httpServer.setAuthentication("testuser", "testpass");
auth = new AuthenticationBuilder()
.addUsername("testuser")
.addPassword("testpass")
.build();
newTransporter(httpServer.getHttpUrl());
PutTask task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
transporter.put(task);
assertEquals(1, httpServer.getLogEntries().size()); // put w/ auth
}

@Test
public void testPut_AuthCache() throws Exception {
session.setConfigProperty(HttpTransporter.PREEMPTIVE_PUT_AUTH, false);
httpServer.setAuthentication("testuser", "testpass");
auth = new AuthenticationBuilder()
.addUsername("testuser")
Expand Down
3 changes: 2 additions & 1 deletion src/site/markdown/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ 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.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` | yes
`aether.connector.http.preemptivePutAuth` | boolean | Should HTTP client use preemptive-authentication for HTTP PUTs only (works only w/ BASIC). By default is enabled (same as Wagon). | `true` | 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.http.supportWebDav` | boolean | If enabled, transport makes best effort to deploy to WebDAV server. This mode is not recommended, better use real Maven Repository Manager instead. | `false` | 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
Expand Down

0 comments on commit 28fec45

Please sign in to comment.