diff --git a/core/src/main/java/ch/cyberduck/core/Profile.java b/core/src/main/java/ch/cyberduck/core/Profile.java index bea4fa65dc0..c2f723ba196 100644 --- a/core/src/main/java/ch/cyberduck/core/Profile.java +++ b/core/src/main/java/ch/cyberduck/core/Profile.java @@ -685,6 +685,9 @@ public Map getProperties() { property -> StringUtils.contains(property, '=') ? substitutor.replace(StringUtils.substringAfter(property, '=')) : StringUtils.EMPTY))); // In profile as dict properties.putAll(this.map(PROPERTIES_KEY)); + if(null != this.getContext()) { + properties.put(CONTEXT_KEY, this.getContext()); + } return properties; } diff --git a/core/src/main/java/ch/cyberduck/core/serializer/HostDictionary.java b/core/src/main/java/ch/cyberduck/core/serializer/HostDictionary.java index 733c8b63a90..2d6b7ed1303 100644 --- a/core/src/main/java/ch/cyberduck/core/serializer/HostDictionary.java +++ b/core/src/main/java/ch/cyberduck/core/serializer/HostDictionary.java @@ -192,6 +192,12 @@ public Host deserialize(final T serialized) { if(customObj != null) { bookmark.setCustom(customObj); } + final Object contextObj = dict.stringForKey("Context"); + if(contextObj != null) { + bookmark.setProperty("Context", contextObj.toString()); + // Also set it on credentials so validate() can access it + bookmark.getCredentials().setProperty("Context", contextObj.toString()); + } final Object labelObj = dict.stringForKey("Labels"); if(labelObj != null) { bookmark.setLabels(new HashSet<>(dict.listForKey("Labels"))); diff --git a/s3/src/main/java/ch/cyberduck/core/auth/AWSSessionCredentialsRetriever.java b/s3/src/main/java/ch/cyberduck/core/auth/AWSSessionCredentialsRetriever.java index 8112fc11b9d..83e4a974d83 100644 --- a/s3/src/main/java/ch/cyberduck/core/auth/AWSSessionCredentialsRetriever.java +++ b/s3/src/main/java/ch/cyberduck/core/auth/AWSSessionCredentialsRetriever.java @@ -75,7 +75,7 @@ public Credentials get() throws BackgroundException { final HttpClientBuilder configuration = builder.build(ProxyFactory.get(), new DisabledTranscriptListener(), new DisabledLoginCallback()); try (CloseableHttpClient client = configuration.build()) { - final HttpRequestBase resource = new HttpGet(new HostUrlProvider().withUsername(false).withPath(true).get(address)); + final HttpRequestBase resource = new HttpGet(url); return client.execute(resource, response -> { switch(response.getStatusLine().getStatusCode()) { case HttpStatus.SC_OK: diff --git a/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java b/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java index 114dd502bfb..ff2fbf6d1c1 100644 --- a/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java +++ b/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java @@ -116,6 +116,10 @@ public String favicon() { @Override public boolean validate(final Credentials credentials, final LoginOptions options) { + // Skip credential validation if Context property is present (HTTP credential provider) + if(credentials.getProperty("Context") != null) { + return true; + } // Password input is disabled for AWS CLI connection profile but requires lookup in AWS CLI configuration. return super.validate(credentials, new LoginOptions(options).token(true)); } diff --git a/s3/src/main/java/ch/cyberduck/core/s3/S3Session.java b/s3/src/main/java/ch/cyberduck/core/s3/S3Session.java index 85abefceb6d..c50e60f936e 100644 --- a/s3/src/main/java/ch/cyberduck/core/s3/S3Session.java +++ b/s3/src/main/java/ch/cyberduck/core/s3/S3Session.java @@ -27,6 +27,7 @@ import ch.cyberduck.core.LoginCallback; import ch.cyberduck.core.Path; import ch.cyberduck.core.PathContainerService; +import ch.cyberduck.core.Profile; import ch.cyberduck.core.Scheme; import ch.cyberduck.core.TemporaryAccessTokens; import ch.cyberduck.core.UrlProvider; @@ -264,10 +265,11 @@ protected S3CredentialsStrategy configureCredentialsStrategy(final HttpClientBui } if(S3Session.isAwsHostname(host.getHostname())) { // Try auto-configure - if(Scheme.isURL(host.getProtocol().getContext())) { - log.debug("Auto-configure credentials from instance metadata {}", host.getProtocol().getContext()); - // Fetch temporary session token from instance metadata - return new AWSSessionCredentialsRetriever(trust, key, host.getProtocol().getContext()); + final String context = preferences.getProperty(Profile.CONTEXT_KEY); + if(Scheme.isURL(context)) { + log.debug("Auto-configure credentials from HTTP endpoint {}", context); + // Fetch temporary session token from HTTP endpoint + return new AWSSessionCredentialsRetriever(trust, key, context); } } if(host.getProtocol().isRoleConfigurable()) {