[java-opensaml] 10/16: HttpClientSecurity -Configuration, -Resolver and tests.
Brent Putman
putmanb at georgetown.edu
Sun Dec 17 00:08:20 EST 2017
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch master
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=123a057449368c7bb36cf369b17afb65f0fd54b8
commit 123a057449368c7bb36cf369b17afb65f0fd54b8
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Fri Dec 15 16:49:15 2017 -0500
HttpClientSecurity -Configuration, -Resolver and tests.
---
.../HttpClientSecurityConfiguration.java | 95 +++++++
.../HttpClientSecurityConfigurationCriterion.java | 113 +++++++++
.../HttpClientSecurityParametersResolver.java | 28 +++
.../impl/BasicHttpClientSecurityConfiguration.java | 272 +++++++++++++++++++++
.../BasicHttpClientSecurityParametersResolver.java | 158 ++++++++++++
.../BasicHttpClientSecurityConfigurationTest.java | 103 ++++++++
...icHttpClientSecurityParametersResolverTest.java | 233 ++++++++++++++++++
.../src/test/resources/logback-test.xml | 4 +
8 files changed, 1006 insertions(+)
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfiguration.java b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfiguration.java
new file mode 100644
index 0000000..2596eae
--- /dev/null
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfiguration.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ * The security configuration information to use when performing HTTP client requests.
+ */
+public interface HttpClientSecurityConfiguration {
+
+ /**
+ * Get an instance of {@link CredentialsProvider} used for authentication by the HttpClient instance.
+ *
+ * @return the credentials provider, or null
+ */
+ @Nullable public CredentialsProvider getCredentialsProvider();
+
+ /**
+ * Get an instance of {@link AuthCache} used for authentication by the HttpClient instance.
+ *
+ * @return the cache, or null
+ *
+ * @since 3.4.0
+ */
+ @Nullable public AuthCache getAuthCache();
+
+ /**
+ * Sets the optional trust engine used in evaluating server TLS credentials.
+ *
+ * @return the trust engine instance to use, or null
+ */
+ @Nullable public TrustEngine<? super X509Credential> getTLSTrustEngine();
+
+ /**
+ * Get the optional criteria set used in evaluating server TLS credentials.
+ *
+ * @return the criteria set instance to use
+ */
+ @Nullable public CriteriaSet getTLSCriteriaSet();
+
+ /**
+ * Get the optional list of TLS protocols.
+ *
+ * @return the TLS protocols, or null
+ */
+ @Nullable public List<String> getTLSProtocols();
+
+ /**
+ * Get the optional list of TLS cipher suites.
+ *
+ * @return the list of TLS cipher suites, or null
+ */
+ @Nullable public List<String> getTLSCipherSuites();
+
+ /**
+ * Get the optional hostname verifier.
+ *
+ * @return the hostname verifier, or null
+ */
+ @Nullable public X509HostnameVerifier getHostnameVerifier();
+
+ /**
+ * Get the optional client TLS credential.
+ *
+ * @return the client TLS credential, or null
+ */
+ @Nullable public X509Credential getClientTLSCredential();
+
+}
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfigurationCriterion.java b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfigurationCriterion.java
new file mode 100644
index 0000000..070bf01
--- /dev/null
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityConfigurationCriterion.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.Criterion;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Criterion which holds one or more instances of {@link HttpClientSecurityConfiguration}.
+ */
+public class HttpClientSecurityConfigurationCriterion implements Criterion {
+
+ /** The list of configuration instances. */
+ @Nonnull @NonnullElements private List<HttpClientSecurityConfiguration> configs;
+
+ /**
+ * Constructor.
+ *
+ * @param configurations list of configuration instances
+ */
+ public HttpClientSecurityConfigurationCriterion(@Nonnull @NonnullElements @NotEmpty final
+ List<HttpClientSecurityConfiguration> configurations) {
+ Constraint.isNotNull(configurations, "List of configurations cannot be null");
+ configs = new ArrayList<>(Collections2.filter(configurations, Predicates.notNull()));
+ Constraint.isGreaterThanOrEqual(1, configs.size(), "At least one configuration is required");
+
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param configurations varargs array of configuration instances
+ */
+ public HttpClientSecurityConfigurationCriterion(@Nonnull @NonnullElements @NotEmpty final
+ HttpClientSecurityConfiguration... configurations) {
+ Constraint.isNotNull(configurations, "List of configurations cannot be null");
+ configs = new ArrayList<>(Collections2.filter(Arrays.asList(configurations), Predicates.notNull()));
+ Constraint.isGreaterThanOrEqual(1, configs.size(), "At least one configuration is required");
+ }
+
+ /**
+ * Get the list of configuration instances.
+ * @return the list of configuration instances
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable @NotEmpty
+ public List<HttpClientSecurityConfiguration> getConfigurations() {
+ return ImmutableList.copyOf(configs);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("HttpClientSecurityConfigurationCriterion [configs=");
+ builder.append(configs);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return configs.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (obj instanceof HttpClientSecurityConfigurationCriterion) {
+ return configs.equals(((HttpClientSecurityConfigurationCriterion) obj).getConfigurations());
+ }
+
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParametersResolver.java b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParametersResolver.java
new file mode 100644
index 0000000..be3d72b
--- /dev/null
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/httpclient/HttpClientSecurityParametersResolver.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.Resolver;
+
+/**
+ * An interface for components which resolve {@link HttpClientSecurityParameters} based on a {@link CriteriaSet}.
+ */
+public interface HttpClientSecurityParametersResolver extends Resolver<HttpClientSecurityParameters, CriteriaSet> {
+
+}
diff --git a/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfiguration.java b/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfiguration.java
new file mode 100644
index 0000000..49b3186
--- /dev/null
+++ b/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfiguration.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.opensaml.security.httpclient.HttpClientSecurityConfiguration;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ * Basic implementation of {@link HttpClientSecurityConfiguration}.
+ */
+public class BasicHttpClientSecurityConfiguration implements HttpClientSecurityConfiguration {
+
+ /** HttpClient credentials provider. */
+ @Nullable private CredentialsProvider credentialsProvider;
+
+ /** HttpClient {@link AuthCache} to allow pre-emptive authentication. */
+ @Nullable private AuthCache authCache;
+
+ /** Optional trust engine used in evaluating server TLS credentials. */
+ @Nullable private TrustEngine<? super X509Credential> tlsTrustEngine;
+
+ /** Optional criteria set used in evaluating server TLS credentials. */
+ @Nullable private CriteriaSet tlsCriteriaSet;
+
+ /** TLS Protocols. */
+ @Nullable private List<String> tlsProtocols;
+
+ /** TLS cipher suites. */
+ @Nullable private List<String> tlsCipherSuites;
+
+ /** The hostname verifier. */
+ @Nullable private X509HostnameVerifier hostnameVerifier;
+
+ /** The X509 credential used for client TLS. */
+ @Nullable private X509Credential clientTLSCredential;
+
+ /**
+ * Get an instance of {@link CredentialsProvider} used for authentication by the HttpClient instance.
+ *
+ * @return the credentials provider, or null
+ */
+ @Nullable public CredentialsProvider getCredentialsProvider() {
+ return credentialsProvider;
+ }
+
+ /**
+ * Set an instance of {@link CredentialsProvider} used for authentication by the HttpClient instance.
+ *
+ * @param provider the credentials provider
+ */
+ public void setCredentialsProvider(@Nullable final CredentialsProvider provider) {
+ credentialsProvider = provider;
+ }
+
+ /**
+ * Get an instance of {@link AuthCache} used for authentication by the HttpClient instance.
+ *
+ * @return the cache, or null
+ *
+ * @since 3.4.0
+ */
+ @Nullable public AuthCache getAuthCache() {
+ return authCache;
+ }
+
+ /**
+ * Set an instance of {@link AuthCache} used for authentication by the HttpClient instance.
+ *
+ * @param cache the auth cache
+ *
+ * @since 3.4.0
+ */
+ public void setAuthCache(@Nullable final AuthCache cache) {
+ authCache = cache;
+ }
+
+
+ /**
+ * A convenience method to set a (single) username and password used for BASIC authentication.
+ * To disable BASIC authentication pass null for the credentials instance.
+ *
+ * <p>
+ * An {@link AuthScope} will be generated which specifies any host, port, scheme and realm.
+ * </p>
+ *
+ * <p>To specify multiple usernames and passwords for multiple host, port, scheme, and realm combinations, instead
+ * provide an instance of {@link CredentialsProvider} via {@link #setCredentialsProvider(CredentialsProvider)}.</p>
+ *
+ * @param credentials the username and password credentials
+ */
+ public void setBasicCredentials(@Nullable final UsernamePasswordCredentials credentials) {
+ setBasicCredentialsWithScope(credentials, null);
+ }
+
+ /**
+ * A convenience method to set a (single) username and password used for BASIC authentication.
+ * To disable BASIC authentication pass null for the credentials instance.
+ *
+ * <p>
+ * If the <code>authScope</code> is null, an {@link AuthScope} will be generated which specifies
+ * any host, port, scheme and realm.
+ * </p>
+ *
+ * <p>To specify multiple usernames and passwords for multiple host, port, scheme, and realm combinations, instead
+ * provide an instance of {@link CredentialsProvider} via {@link #setCredentialsProvider(CredentialsProvider)}.</p>
+ *
+ * @param credentials the username and password credentials
+ * @param scope the HTTP client auth scope with which to scope the credentials, may be null
+ */
+ public void setBasicCredentialsWithScope(@Nullable final UsernamePasswordCredentials credentials,
+ @Nullable final AuthScope scope) {
+
+ if (credentials != null) {
+ AuthScope authScope = scope;
+ if (authScope == null) {
+ authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT);
+ }
+ final BasicCredentialsProvider provider = new BasicCredentialsProvider();
+ provider.setCredentials(authScope, credentials);
+ credentialsProvider = provider;
+ } else {
+ credentialsProvider = null;
+ }
+
+ }
+
+ /**
+ * Sets the optional trust engine used in evaluating server TLS credentials.
+ *
+ * @return the trust engine instance to use, or null
+ */
+ @Nullable public TrustEngine<? super X509Credential> getTLSTrustEngine() {
+ return tlsTrustEngine;
+ }
+
+ /**
+ * Sets the optional trust engine used in evaluating server TLS credentials.
+ *
+ * @param engine the trust engine instance to use
+ */
+ public void setTLSTrustEngine(@Nullable final TrustEngine<? super X509Credential> engine) {
+ tlsTrustEngine = engine;
+ }
+
+ /**
+ * Get the optional criteria set used in evaluating server TLS credentials.
+ *
+ * @return the criteria set instance to use
+ */
+ @Nullable public CriteriaSet getTLSCriteriaSet() {
+ return tlsCriteriaSet;
+ }
+
+ /**
+ * Set the optional criteria set used in evaluating server TLS credentials.
+ *
+ * @param criteriaSet the new criteria set instance to use
+ */
+ public void setTLSCriteriaSet(@Nullable final CriteriaSet criteriaSet) {
+ tlsCriteriaSet = criteriaSet;
+ }
+
+ /**
+ * Get the optional list of TLS protocols.
+ *
+ * @return the TLS protocols, or null
+ */
+ @Nullable public List<String> getTLSProtocols() {
+ return tlsProtocols;
+ }
+
+ /**
+ * Set the optional list of TLS protocols.
+ *
+ * @param protocols the TLS protocols or null
+ */
+ public void setTLSProtocols(@Nullable final Collection<String> protocols) {
+ tlsProtocols = new ArrayList<>(StringSupport.normalizeStringCollection(protocols));
+ if (tlsProtocols.isEmpty()) {
+ tlsProtocols = null;
+ }
+ }
+
+ /**
+ * Get the optional list of TLS cipher suites.
+ *
+ * @return the list of TLS cipher suites, or null
+ */
+ @Nullable public List<String> getTLSCipherSuites() {
+ return tlsCipherSuites;
+ }
+
+ /**
+ * Set the optional list of TLS cipher suites.
+ *
+ * @param cipherSuites the TLS cipher suites, or null
+ */
+ public void setTLSCipherSuites(@Nullable final Collection<String> cipherSuites) {
+ tlsCipherSuites = new ArrayList<>(StringSupport.normalizeStringCollection(cipherSuites));
+ if (tlsCipherSuites.isEmpty()) {
+ tlsCipherSuites = null;
+ }
+ }
+
+ /**
+ * Get the optional hostname verifier.
+ *
+ * @return the hostname verifier, or null
+ */
+ @Nullable public X509HostnameVerifier getHostnameVerifier() {
+ return hostnameVerifier;
+ }
+
+ /**
+ * Set the optional hostname verifier.
+ *
+ * @param verifier the hostname verifier, or null
+ */
+ public void setHostnameVerifier(@Nullable final X509HostnameVerifier verifier) {
+ hostnameVerifier = verifier;
+ }
+
+ /**
+ * Get the optional client TLS credential.
+ *
+ * @return the client TLS credential, or null
+ */
+ @Nullable public X509Credential getClientTLSCredential() {
+ return clientTLSCredential;
+ }
+
+ /**
+ * Set the optional client TLS credential.
+ *
+ * @param credential the client TLS credential, or null
+ */
+ public void setClientTLSCredential(@Nullable final X509Credential credential) {
+ clientTLSCredential = credential;
+ }
+
+}
diff --git a/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolver.java b/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolver.java
new file mode 100644
index 0000000..b77161b
--- /dev/null
+++ b/opensaml-security-impl/src/main/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolver.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient.impl;
+
+import java.security.Key;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.security.credential.CredentialSupport;
+import org.opensaml.security.httpclient.HttpClientSecurityConfiguration;
+import org.opensaml.security.httpclient.HttpClientSecurityConfigurationCriterion;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.opensaml.security.httpclient.HttpClientSecurityParametersResolver;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.ObjectSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/**
+ * Basic implementation of {@link HttpClientSecurityParametersResolver}.
+ *
+ * <p>
+ * The following {@link net.shibboleth.utilities.java.support.resolver.Criterion} inputs are supported:
+ * <ul>
+ * <li>{@link HttpClientSecurityConfigurationCriterion} - required</li>
+ * </ul>
+ * </p>
+ */
+public class BasicHttpClientSecurityParametersResolver implements HttpClientSecurityParametersResolver {
+
+ /** Logger. */
+ private Logger log = LoggerFactory.getLogger(BasicHttpClientSecurityParametersResolver.class);
+
+ /** {@inheritDoc} */
+ public Iterable<HttpClientSecurityParameters> resolve(@Nonnull final CriteriaSet criteria)
+ throws ResolverException {
+
+ final HttpClientSecurityParameters params = resolveSingle(criteria);
+ if (params != null) {
+ return Collections.singletonList(params);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ /** {@inheritDoc} */
+ public HttpClientSecurityParameters resolveSingle(@Nonnull final CriteriaSet criteria) throws ResolverException {
+ Constraint.isNotNull(criteria, "CriteriaSet was null");
+ Constraint.isNotNull(criteria.get(HttpClientSecurityConfigurationCriterion.class),
+ "Resolver requires an instance of HttpClientSecurityConfigurationCriterion");
+
+ final HttpClientSecurityParameters params = new HttpClientSecurityParameters();
+
+ resolveAndPopulateParams(params, criteria);
+
+ if (validate(params)) {
+ logResult(params);
+ return params;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Resolve and populate all parametersu.
+ *
+ * @param params the parameters instance to populate
+ * @param criteria the criteria to process
+ */
+ protected void resolveAndPopulateParams(@Nonnull final HttpClientSecurityParameters params,
+ @Nonnull final CriteriaSet criteria) {
+
+ final List<HttpClientSecurityConfiguration> configs =
+ criteria.get(HttpClientSecurityConfigurationCriterion.class).getConfigurations();
+
+ for (final HttpClientSecurityConfiguration config : configs) {
+ params.setAuthCache(ObjectSupport.firstNonNull(params.getAuthCache(),
+ config.getAuthCache()));
+ params.setClientTLSCredential(ObjectSupport.firstNonNull(params.getClientTLSCredential(),
+ config.getClientTLSCredential()));
+ params.setCredentialsProvider(ObjectSupport.firstNonNull(params.getCredentialsProvider(),
+ config.getCredentialsProvider()));
+ params.setHostnameVerifier(ObjectSupport.firstNonNull(params.getHostnameVerifier(),
+ config.getHostnameVerifier()));
+ params.setTLSCipherSuites(ObjectSupport.firstNonNull(params.getTLSCipherSuites(),
+ config.getTLSCipherSuites()));
+ params.setTLSCriteriaSet(ObjectSupport.firstNonNull(params.getTLSCriteriaSet(),
+ config.getTLSCriteriaSet()));
+ params.setTLSProtocols(ObjectSupport.firstNonNull(params.getTLSProtocols(),
+ config.getTLSProtocols()));
+ params.setTLSTrustEngine(ObjectSupport.<TrustEngine<? super X509Credential>>firstNonNull(
+ params.getTLSTrustEngine(), config.getTLSTrustEngine()));
+ }
+ }
+
+ /**
+ * Validate that the {@link HttpClientSecurityParameters} instance has all the required properties populated.
+ *
+ * @param params the parameters instance to evaluate
+ *
+ * @return true if parameters instance passes validation, false otherwise
+ */
+ protected boolean validate(@Nonnull final HttpClientSecurityParameters params) {
+ // Default impl is no required data.
+ return true;
+ }
+
+ /**
+ * Log the resolved parameters.
+ *
+ * @param params the resolved param
+ */
+ protected void logResult(@Nonnull final HttpClientSecurityParameters params) {
+ if (log.isDebugEnabled()) {
+ log.debug("Resolved HttpClientSecurityParameters:");
+
+ final Key clientTLSKey = CredentialSupport.extractSigningKey(params.getClientTLSCredential());
+ if (clientTLSKey != null) {
+ log.debug("\tClient TLS credential with key algorithm: {}", clientTLSKey.getAlgorithm());
+ } else {
+ log.debug("\tClient TLS credential: null");
+ }
+
+ log.debug("\tHostnameVerifier: {}", params.getHostnameVerifier() != null ? "present" : "null");
+ log.debug("\tTLS TrustEngine: {}", params.getTLSTrustEngine() != null ? "present" : "null");
+ log.debug("\tTLS CriteriaSet: {}", params.getTLSCriteriaSet() != null ? "present" : "null");
+
+ log.debug("\tTLS cipher suites: {}", params.getTLSCipherSuites());
+ log.debug("\tTLS protocols: {}", params.getTLSProtocols());
+
+ log.debug("\tAuthCache: {}", params.getAuthCache() != null ? "present" : "null");
+ log.debug("\tCredentialsProvider: {}", params.getCredentialsProvider() != null ? "present" : "null");
+ }
+ }
+
+}
diff --git a/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfigurationTest.java b/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfigurationTest.java
new file mode 100644
index 0000000..874766a
--- /dev/null
+++ b/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityConfigurationTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient.impl;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.security.cert.CertificateException;
+
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.conn.ssl.StrictHostnameVerifier;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.credential.CredentialSupport;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.X509Support;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Lists;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ *
+ */
+public class BasicHttpClientSecurityConfigurationTest {
+
+ private X509Credential x509Credential;
+
+ @BeforeMethod
+ protected void setUp() throws CertificateException, URISyntaxException {
+ x509Credential = CredentialSupport.getSimpleCredential(
+ X509Support.decodeCertificate(new File(this.getClass().getResource("/data/certificate.pem").toURI())), null);
+ }
+
+ @Test
+ public void testBasic() {
+ BasicHttpClientSecurityConfiguration config = new BasicHttpClientSecurityConfiguration();
+ config.setAuthCache(new BasicAuthCache());
+ config.setClientTLSCredential(x509Credential);
+ config.setCredentialsProvider(new BasicCredentialsProvider());
+ config.setHostnameVerifier(new StrictHostnameVerifier());
+ config.setTLSCipherSuites(Lists.newArrayList("test"));
+ config.setTLSCriteriaSet(new CriteriaSet());
+ config.setTLSProtocols(Lists.newArrayList("test"));
+ config.setTLSTrustEngine(new MockTrustEngine());
+
+ Assert.assertNotNull(config.getAuthCache());
+ Assert.assertNotNull(config.getClientTLSCredential());
+ Assert.assertNotNull(config.getCredentialsProvider());
+ Assert.assertNotNull(config.getHostnameVerifier());
+ Assert.assertNotNull(config.getTLSCipherSuites());
+ Assert.assertNotNull(config.getTLSCriteriaSet());
+ Assert.assertNotNull(config.getTLSProtocols());
+ Assert.assertNotNull(config.getTLSTrustEngine());
+ }
+
+ @Test
+ public void testEmptyLists() {
+ BasicHttpClientSecurityConfiguration config = new BasicHttpClientSecurityConfiguration();
+ config.setTLSCipherSuites(Lists.<String>newArrayList());
+ config.setTLSProtocols(Lists.<String>newArrayList());
+
+ Assert.assertNull(config.getTLSCipherSuites());
+ Assert.assertNull(config.getTLSProtocols());
+ }
+
+ @Test
+ public void testCredentialsProvider() {
+ BasicHttpClientSecurityConfiguration config = new BasicHttpClientSecurityConfiguration();
+ config.setBasicCredentials(new UsernamePasswordCredentials("test", "test"));
+
+ Assert.assertNotNull(config.getCredentialsProvider());
+ }
+
+
+ // Helpers
+
+ public static class MockTrustEngine implements TrustEngine<X509Credential> {
+ public boolean validate(X509Credential token, CriteriaSet trustBasisCriteria) throws SecurityException {
+ return false;
+ }
+ }
+
+}
diff --git a/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolverTest.java b/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolverTest.java
new file mode 100644
index 0000000..1d54639
--- /dev/null
+++ b/opensaml-security-impl/src/test/java/org/opensaml/security/httpclient/impl/BasicHttpClientSecurityParametersResolverTest.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.security.httpclient.impl;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.security.KeyException;
+import java.security.cert.CertificateException;
+
+import org.apache.http.conn.ssl.StrictHostnameVerifier;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.credential.CredentialSupport;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.security.httpclient.HttpClientSecurityConfigurationCriterion;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.X509Support;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Lists;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/**
+ *
+ */
+public class BasicHttpClientSecurityParametersResolverTest {
+
+ private BasicHttpClientSecurityParametersResolver resolver;
+
+ private X509Credential x509Credential1, x509Credential2, x509Credential3;
+
+ @BeforeMethod
+ protected void setUp() throws CertificateException, URISyntaxException, KeyException {
+ resolver = new BasicHttpClientSecurityParametersResolver();
+ x509Credential1 = CredentialSupport.getSimpleCredential(
+ X509Support.decodeCertificate(new File(this.getClass().getResource("/data/certificate.pem").toURI())),
+ KeySupport.decodePrivateKey(new File(this.getClass().getResource("/data/rsa-privkey-nopass.pem").toURI()), null)
+ );
+ x509Credential2 = CredentialSupport.getSimpleCredential(
+ X509Support.decodeCertificate(new File(this.getClass().getResource("/data/certificate.pem").toURI())),
+ KeySupport.decodePrivateKey(new File(this.getClass().getResource("/data/rsa-privkey-nopass.pem").toURI()), null)
+ );
+ x509Credential3 = CredentialSupport.getSimpleCredential(
+ X509Support.decodeCertificate(new File(this.getClass().getResource("/data/certificate.pem").toURI())),
+ KeySupport.decodePrivateKey(new File(this.getClass().getResource("/data/rsa-privkey-nopass.pem").toURI()), null)
+ );
+ }
+
+ @Test
+ public void testSingleConfigFullyPopulated() throws ResolverException {
+ CriteriaSet criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ buildBaseConfiguration(x509Credential1)));
+
+ HttpClientSecurityParameters params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getAuthCache());
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertNotNull(params.getCredentialsProvider());
+ Assert.assertNotNull(params.getHostnameVerifier());
+ Assert.assertNotNull(params.getTLSCipherSuites());
+ Assert.assertNotNull(params.getTLSCriteriaSet());
+ Assert.assertNotNull(params.getTLSProtocols());
+ Assert.assertNotNull(params.getTLSTrustEngine());
+ }
+
+ @Test
+ public void testSingleConfigEmpty() throws ResolverException {
+ CriteriaSet criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ new BasicHttpClientSecurityConfiguration()));
+
+ HttpClientSecurityParameters params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNull(params.getAuthCache());
+ Assert.assertNull(params.getClientTLSCredential());
+ Assert.assertNull(params.getCredentialsProvider());
+ Assert.assertNull(params.getHostnameVerifier());
+ Assert.assertNull(params.getTLSCipherSuites());
+ Assert.assertNull(params.getTLSCriteriaSet());
+ Assert.assertNull(params.getTLSProtocols());
+ Assert.assertNull(params.getTLSTrustEngine());
+ }
+
+ @Test
+ public void testMultipleConfigsSimple() throws ResolverException {
+ CriteriaSet criteria;
+ HttpClientSecurityParameters params;
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ buildBaseConfiguration(x509Credential1),
+ new BasicHttpClientSecurityConfiguration(),
+ new BasicHttpClientSecurityConfiguration()));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getAuthCache());
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertNotNull(params.getCredentialsProvider());
+ Assert.assertNotNull(params.getHostnameVerifier());
+ Assert.assertNotNull(params.getTLSCipherSuites());
+ Assert.assertNotNull(params.getTLSCriteriaSet());
+ Assert.assertNotNull(params.getTLSProtocols());
+ Assert.assertNotNull(params.getTLSTrustEngine());
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ new BasicHttpClientSecurityConfiguration(),
+ buildBaseConfiguration(x509Credential1),
+ new BasicHttpClientSecurityConfiguration()));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getAuthCache());
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertNotNull(params.getCredentialsProvider());
+ Assert.assertNotNull(params.getHostnameVerifier());
+ Assert.assertNotNull(params.getTLSCipherSuites());
+ Assert.assertNotNull(params.getTLSCriteriaSet());
+ Assert.assertNotNull(params.getTLSProtocols());
+ Assert.assertNotNull(params.getTLSTrustEngine());
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ new BasicHttpClientSecurityConfiguration(),
+ new BasicHttpClientSecurityConfiguration(),
+ buildBaseConfiguration(x509Credential1)));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getAuthCache());
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertNotNull(params.getCredentialsProvider());
+ Assert.assertNotNull(params.getHostnameVerifier());
+ Assert.assertNotNull(params.getTLSCipherSuites());
+ Assert.assertNotNull(params.getTLSCriteriaSet());
+ Assert.assertNotNull(params.getTLSProtocols());
+ Assert.assertNotNull(params.getTLSTrustEngine());
+ }
+
+ @Test
+ public void testMultipleConfigsLayered() throws ResolverException {
+ CriteriaSet criteria;
+ HttpClientSecurityParameters params;
+
+ BasicHttpClientSecurityConfiguration config1 = buildBaseConfiguration(x509Credential1);
+ BasicHttpClientSecurityConfiguration config2 = buildBaseConfiguration(x509Credential2);
+ BasicHttpClientSecurityConfiguration config3 = buildBaseConfiguration(x509Credential3);
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ config1,
+ config2,
+ config3));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertSame(params.getClientTLSCredential(), config1.getClientTLSCredential());
+
+ config1.setClientTLSCredential(null);
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ config1,
+ config2,
+ config3));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertSame(params.getClientTLSCredential(), config2.getClientTLSCredential());
+
+ config2.setClientTLSCredential(null);
+
+ criteria = new CriteriaSet(new HttpClientSecurityConfigurationCriterion(
+ config1,
+ config2,
+ config3));
+
+ params = resolver.resolveSingle(criteria);
+
+ Assert.assertNotNull(params);;
+ Assert.assertNotNull(params.getClientTLSCredential());
+ Assert.assertSame(params.getClientTLSCredential(), config3.getClientTLSCredential());
+ }
+
+
+ // Helpers
+
+ private BasicHttpClientSecurityConfiguration buildBaseConfiguration(X509Credential x509Credential) {
+ BasicHttpClientSecurityConfiguration config = new BasicHttpClientSecurityConfiguration();
+ config.setAuthCache(new BasicAuthCache());
+ config.setClientTLSCredential(x509Credential);
+ config.setCredentialsProvider(new BasicCredentialsProvider());
+ config.setHostnameVerifier(new StrictHostnameVerifier());
+ config.setTLSCipherSuites(Lists.newArrayList("test"));
+ config.setTLSCriteriaSet(new CriteriaSet());
+ config.setTLSProtocols(Lists.newArrayList("test"));
+ config.setTLSTrustEngine(new MockTrustEngine());
+ return config;
+ }
+
+ public static class MockTrustEngine implements TrustEngine<X509Credential> {
+ public boolean validate(X509Credential token, CriteriaSet trustBasisCriteria) throws SecurityException {
+ return false;
+ }
+ }
+
+}
diff --git a/opensaml-security-impl/src/test/resources/logback-test.xml b/opensaml-security-impl/src/test/resources/logback-test.xml
index d03dd06..7374663 100644
--- a/opensaml-security-impl/src/test/resources/logback-test.xml
+++ b/opensaml-security-impl/src/test/resources/logback-test.xml
@@ -8,6 +8,10 @@
</encoder>
</appender>
+ <logger name="org.opensaml.security.httpclient">
+ <level value="DEBUG"/>
+ </logger>
+
<logger name="org.opensaml">
<level value="WARN"/>
</logger>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list