[java-opensaml] branch main updated: OSJ-384 - HTTP client changes to allow for preemptive basic auth
Scott Cantor
cantor.2 at osu.edu
Mon Jul 24 15:25:20 UTC 2023
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=c91eb3a4f9e32b2fd9a45e482d6b88a6952cf98c
The following commit(s) were added to refs/heads/main by this push:
new c91eb3a4f OSJ-384 - HTTP client changes to allow for preemptive basic auth
c91eb3a4f is described below
commit c91eb3a4f9e32b2fd9a45e482d6b88a6952cf98c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jul 24 11:24:50 2023 -0400
OSJ-384 - HTTP client changes to allow for preemptive basic auth
https://shibboleth.atlassian.net/browse/OSJ-384
Add new context builder APIs to allow for preemptive basic-auth.
Retrofitted change to HTTP metrics reporter and metadata resolvers.
---
.../opensaml/core/metrics/impl/HTTPReporter.java | 5 ++-
.../impl/AbstractDynamicHTTPMetadataResolver.java | 7 ++--
.../resolver/impl/HTTPMetadataResolver.java | 5 ++-
.../httpclient/HttpClientSecurityParameters.java | 38 ++++++++++++++++++++++
.../httpclient/HttpClientSecuritySupport.java | 33 +++++++++++++++++++
5 files changed, 77 insertions(+), 11 deletions(-)
diff --git a/opensaml-core-impl/src/main/java/org/opensaml/core/metrics/impl/HTTPReporter.java b/opensaml-core-impl/src/main/java/org/opensaml/core/metrics/impl/HTTPReporter.java
index d7d105524..d20ef3afc 100644
--- a/opensaml-core-impl/src/main/java/org/opensaml/core/metrics/impl/HTTPReporter.java
+++ b/opensaml-core-impl/src/main/java/org/opensaml/core/metrics/impl/HTTPReporter.java
@@ -60,7 +60,6 @@ import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.component.InitializableComponent;
import net.shibboleth.shared.component.UninitializedComponentException;
-import net.shibboleth.shared.httpclient.HttpClientSupport;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
@@ -297,8 +296,8 @@ public class HTTPReporter extends ScheduledReporter implements InitializableComp
* @return the client context instance
*/
@Nonnull private HttpClientContext buildHttpContext(@Nonnull final HttpRequest request) {
- final HttpClientContext clientContext = HttpClientSupport.buildHttpClientContext();
- HttpClientSecuritySupport.marshalSecurityParameters(clientContext, httpClientSecurityParameters, false);
+ final HttpClientContext clientContext =
+ HttpClientSecuritySupport.buildHttpClientContext(httpClientSecurityParameters);
HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(clientContext, request);
return clientContext;
}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
index 93ddbf0a6..49f9b094c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
@@ -318,12 +318,9 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
* @return a new instance of {@link HttpClientContext}
*/
@Nonnull protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
- final HttpClientContext context = HttpClientContext.create();
- assert context != null;
-
- HttpClientSecuritySupport.marshalSecurityParameters(context, httpClientSecurityParameters, true);
+ final HttpClientContext context =
+ HttpClientSecuritySupport.buildHttpClientContext(httpClientSecurityParameters);
HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(context, request);
-
return context;
}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
index b43a8882d..822532c71 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
@@ -271,10 +271,9 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver impl
* @return a new instance of {@link HttpClientContext}
*/
@Nonnull protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
- final HttpClientContext context = HttpClientContext.create();
- assert context != null;
+ final HttpClientContext context =
+ HttpClientSecuritySupport.buildHttpClientContext(httpClientSecurityParameters);
- HttpClientSecuritySupport.marshalSecurityParameters(context, httpClientSecurityParameters, true);
HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(context, request);
return context;
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParameters.java b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParameters.java
index 4517530bd..42c79dc45 100644
--- a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParameters.java
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParameters.java
@@ -20,11 +20,15 @@ package org.opensaml.security.httpclient;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.net.ssl.HostnameVerifier;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.primitive.StringSupport;
import net.shibboleth.shared.resolver.CriteriaSet;
@@ -33,6 +37,8 @@ import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.HttpHost;
import org.opensaml.security.trust.TrustEngine;
import org.opensaml.security.x509.X509Credential;
@@ -44,6 +50,9 @@ public class HttpClientSecurityParameters {
/** HttpClient credentials provider. */
@Nullable private CredentialsProvider credentialsProvider;
+ /** Map of host specifications to basic-auth credentials to be applied preemptively. */
+ @Nullable private Map<HttpHost,UsernamePasswordCredentials> preemptiveBasicAuthMap;
+
/** HttpClient {@link AuthCache} to allow pre-emptive authentication. */
@Nullable private AuthCache authCache;
@@ -90,6 +99,35 @@ public class HttpClientSecurityParameters {
return this;
}
+ /**
+ * Install a map of rules for preemptive basic authentication using the supplied hosts and credentials.
+ *
+ * <p>Use of this feature requires that the eventual {@link HttpClientContext} used be built using
+ * {@link HttpClientSecuritySupport#buildHttpClientContext(HttpClientSecurityParameters)}.</p>
+ *
+ * @param map preemptive basic-auth map
+ *
+ * @return this object
+ *
+ * @since 5.0.0
+ */
+ @Nonnull public HttpClientSecurityParameters setPreemptiveBasicAuthMap(
+ @Nullable final Map<HttpHost,UsernamePasswordCredentials> map) {
+ preemptiveBasicAuthMap = map != null ? CollectionSupport.copyToMap(map) : null;
+ return this;
+ }
+
+ /**
+ * Get the map of rules for preemptive basic authentication using the supplied hosts and credentials.
+ *
+ * @return basic-auth rule map or null
+ *
+ * @since 5.0.0
+ */
+ @Nullable @Unmodifiable @NotLive public Map<HttpHost,UsernamePasswordCredentials> getPreemptiveBasicAuthMap() {
+ return preemptiveBasicAuthMap;
+ }
+
/**
* Get an instance of {@link AuthCache} used for authentication by the HttpClient instance.
*
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecuritySupport.java b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecuritySupport.java
index 0d6e3b0fb..ee1a342d5 100644
--- a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecuritySupport.java
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecuritySupport.java
@@ -27,12 +27,16 @@ import static org.opensaml.security.httpclient.HttpClientSecurityConstants.CONTE
import static org.opensaml.security.httpclient.HttpClientSecurityConstants.CONTEXT_KEY_SERVER_TLS_FAILURE_IS_FATAL;
import java.net.URISyntaxException;
+import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.net.ssl.SSLPeerUnverifiedException;
+import org.apache.hc.client5.http.ContextBuilder;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.security.credential.UsageType;
@@ -119,6 +123,35 @@ public final class HttpClientSecuritySupport {
}
}
+ /**
+ * Builds a new {@link HttpClientContext} and marshals the supplied {@link HttpClientSecurityParameters}
+ * into it.
+ *
+ * @param securityParameters the parameters to apply to the context
+ *
+ * @return the fresh context
+ *
+ * @since 5.0.0
+ */
+ @Nonnull public static HttpClientContext buildHttpClientContext(
+ @Nullable final HttpClientSecurityParameters securityParameters) {
+ final ContextBuilder builder = ContextBuilder.create();
+
+ if (securityParameters != null) {
+ final Map<HttpHost,UsernamePasswordCredentials> basicAuthMap =
+ securityParameters.getPreemptiveBasicAuthMap();
+ if (basicAuthMap != null) {
+ basicAuthMap.forEach(builder::preemptiveBasicAuth);
+ }
+ }
+
+ final HttpClientContext context = builder.build();
+ assert context != null;
+
+ marshalSecurityParameters(context, securityParameters, true);
+ return context;
+ }
+
/**
* Marshal the supplied {@link HttpClientSecurityParameters} to the supplied {@link HttpClientContext}.
*
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list