[java-opensaml] 02/16: Work on SOAP client security and SAML 2 artifact decoder.

Brent Putman putmanb at georgetown.edu
Fri Sep 21 22:48:40 EDT 2018


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=02a67e6d7d489587d69b84cc080ef97405b76e18

commit 02a67e6d7d489587d69b84cc080ef97405b76e18
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Thu May 17 18:23:08 2018 -0400

    Work on SOAP client security and SAML 2 artifact decoder.
---
 .../soap/SAMLSOAPClientContextBuilder.java         | 61 ++++++++++++++++-
 .../binding/decoding/impl/HTTPArtifactDecoder.java | 51 +++++++++++++++
 .../HttpClientSecurityConfigurationInitalizer.java | 37 +++++++++++
 .../services/org.opensaml.core.config.Initializer  |  3 +-
 .../opensaml/soap/client/SOAPClientContext.java    | 28 +++++++-
 .../client/http/PipelineFactoryHttpSOAPClient.java | 35 ++++++++--
 .../SOAPClientSecurityContext.java}                | 37 ++++++-----
 .../SOAPClientSecurityProfileIdLookupFunction.java | 76 ++++++++++++++++++++++
 .../soap/client/security/package-info.java         | 19 ++++++
 9 files changed, 322 insertions(+), 25 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/messaging/soap/SAMLSOAPClientContextBuilder.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/messaging/soap/SAMLSOAPClientContextBuilder.java
index 188893c..1b182e8 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/messaging/soap/SAMLSOAPClientContextBuilder.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/messaging/soap/SAMLSOAPClientContextBuilder.java
@@ -41,9 +41,12 @@ import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
 import org.opensaml.security.messaging.HttpClientSecurityContext;
+import org.opensaml.soap.client.SOAPClientContext;
+import org.opensaml.soap.client.security.SOAPClientSecurityContext;
 
 import com.google.common.base.Function;
 
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 
 //TODO when impl finished, document required vs optional data and derivation rules
@@ -78,6 +81,12 @@ public class SAMLSOAPClientContextBuilder<InboundMessageType extends SAMLObject,
     /** TLS CriteriaSet strategy. */
     private Function<MessageContext<?>, CriteriaSet> tlsCriteriaSetStrategy;
     
+    /** SOAP client message pipeline name. */
+    private String pipelineName;
+    
+    /** SOAP client security configuration profile ID. */
+    private String securityConfigurationProfileId;
+    
     /**
      * Get the outbound message.
      * 
@@ -231,7 +240,7 @@ public class SAMLSOAPClientContextBuilder<InboundMessageType extends SAMLObject,
     /**
      * Get the TLS CriteriaSet strategy.
      * 
-     * @return Returns the tlsCriteriaSetStrategy.
+     * @return the TLS CriteriaSet strategy, or null
      */
     @Nullable public Function<MessageContext<?>, CriteriaSet> getTLSCriteriaSetStrategy() {
         if (tlsCriteriaSetStrategy != null) {
@@ -254,6 +263,48 @@ public class SAMLSOAPClientContextBuilder<InboundMessageType extends SAMLObject,
     }
 
     /**
+     * Get the SOAP client message pipeline name to use.
+     * 
+     * @return the pipeline name, or null
+     */
+    @Nullable public String getPipelineName() {
+        return pipelineName;
+    }
+
+    /**
+     * Set the SOAP client message pipeline name to use.
+     * 
+     * @param name the pipeline name, or null
+     * @return this builder instance
+     */
+    @Nonnull public SAMLSOAPClientContextBuilder<InboundMessageType, OutboundMessageType>
+            setPipelineName(@Nullable final String name) {
+        pipelineName = StringSupport.trimOrNull(name);
+        return this;
+    }
+    
+    /**
+     * Get the SOAP client security configuration profile ID to use.
+     * 
+     * @return the client security configuration profile ID, or null
+     */
+    @Nullable public String getSecurityConfigurationProfileId() {
+        return securityConfigurationProfileId;
+    }
+
+    /**
+     * Set the SOAP client security configuration profile ID to use.
+     * 
+     * @param profileID the profile ID, or null
+     * @return this builder instance
+     */
+    @Nonnull public SAMLSOAPClientContextBuilder<InboundMessageType, OutboundMessageType>
+            setSecurityConfigurationProfileId(@Nullable final String profileId) {
+        securityConfigurationProfileId = StringSupport.trimOrNull(profileId);
+        return this;
+    }
+
+    /**
      * Build the new operation context.
      * 
      * @return the operation context
@@ -279,6 +330,14 @@ public class SAMLSOAPClientContextBuilder<InboundMessageType extends SAMLObject,
         // This is just so it's easy to change.
         final BaseContext parent = opContext;
         
+        if (getPipelineName() != null) {
+            parent.getSubcontext(SOAPClientContext.class, true).setPipelineName(getPipelineName());
+        }
+        
+        if (getSecurityConfigurationProfileId() != null) {
+            parent.getSubcontext(SOAPClientSecurityContext.class, true).setSecurityConfigurationProfileId(getSecurityConfigurationProfileId());
+        }
+        
         //TODO is this required always?
         final String selfID = getSelfEntityID();
         if (selfID != null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPArtifactDecoder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPArtifactDecoder.java
index fb21fb6..a7c6b25 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPArtifactDecoder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPArtifactDecoder.java
@@ -59,6 +59,7 @@ import org.opensaml.saml.saml2.metadata.ArtifactResolutionService;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.security.SecurityException;
 import org.opensaml.soap.client.SOAPClient;
+import org.opensaml.soap.client.http.PipelineFactoryHttpSOAPClient;
 import org.opensaml.soap.common.SOAPException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -105,6 +106,12 @@ public class HTTPArtifactDecoder extends BaseHttpServletRequestXMLMessageDecoder
     /** SOAP client. */
     private SOAPClient soapClient;
     
+    /** The SOAP client message pipeline name. */
+    private String soapPipelineName;
+    
+    /** SOAP client security configuration profile ID. */
+    private String soapClientSecurityConfigurationProfileId;
+    
     /** Identifier generation strategy. */
     private IdentifierGenerationStrategy idStrategy;
 
@@ -305,6 +312,47 @@ public class HTTPArtifactDecoder extends BaseHttpServletRequestXMLMessageDecoder
         ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
         soapClient = client;
     }
+    
+    /**
+     * Get the name of the specific SOAP client message pipeline to use, 
+     * for example with {@link PipelineFactoryHttpSOAPClient}. 
+     * 
+     * @return the pipeline name, or null
+     */
+    @Nullable public String getSOAPPipelineName() {
+        return soapPipelineName;
+    }
+
+    /**
+     * Set the name of the specific SOAP client message pipeline to use, 
+     * for example with {@link PipelineFactoryHttpSOAPClient}. 
+     * 
+     * @param name the pipeline name, or null
+     */
+    public void setSOAPPipelineName(@Nullable final String name) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        soapPipelineName = StringSupport.trimOrNull(name);
+    }
+    
+    /**
+     * Get the SOAP client security configuration profile ID to use.
+     * 
+     * @return the client security configuration profile ID, or null
+     */
+    @Nullable public String getSOAPClientSecurityConfigurationProfileId() {
+        return soapClientSecurityConfigurationProfileId;
+    }
+
+    /**
+     * Set the SOAP client security configuration profile ID to use.
+     * 
+     * @param profileID the profile ID, or null
+     * @return this builder instance
+     */
+    @Nonnull public void setSOAPClientSecurityConfigurationProfileId(@Nullable final String profileId) {
+        soapClientSecurityConfigurationProfileId = StringSupport.trimOrNull(profileId);
+    }
 
     /** {@inheritDoc} */
     @Nonnull @NotEmpty public String getBindingURI() {
@@ -358,6 +406,7 @@ public class HTTPArtifactDecoder extends BaseHttpServletRequestXMLMessageDecoder
      */
     private void processArtifact(final MessageContext messageContext, final HttpServletRequest request) 
             throws MessageDecodingException {
+        
         final String encodedArtifact = StringSupport.trimOrNull(request.getParameter("SAMLart"));
         if (encodedArtifact == null) {
             log.error("URL SAMLart parameter was missing or did not contain a value.");
@@ -404,6 +453,8 @@ public class HTTPArtifactDecoder extends BaseHttpServletRequestXMLMessageDecoder
             final InOutOperationContext<SAMLObject, ArtifactResolve> opContext = new SAMLSOAPClientContextBuilder()
                     .setOutboundMessage(buildArtifactResolveRequestMessage(
                             artifact, ars.getLocation(), peerRoleDescriptor, selfEntityID))
+                    .setPipelineName(getSOAPPipelineName())
+                    .setSecurityConfigurationProfileId(getSOAPClientSecurityConfigurationProfileId())
                     .setPeerRoleDescriptor(peerRoleDescriptor)
                     .setSelfEntityID(selfEntityID)
                     .build();
diff --git a/opensaml-security-impl/src/main/java/org/opensaml/security/config/impl/HttpClientSecurityConfigurationInitalizer.java b/opensaml-security-impl/src/main/java/org/opensaml/security/config/impl/HttpClientSecurityConfigurationInitalizer.java
new file mode 100644
index 0000000..d08ddc8
--- /dev/null
+++ b/opensaml-security-impl/src/main/java/org/opensaml/security/config/impl/HttpClientSecurityConfigurationInitalizer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.impl;
+
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.config.InitializationException;
+import org.opensaml.core.config.Initializer;
+import org.opensaml.security.httpclient.HttpClientSecurityConfiguration;
+import org.opensaml.security.httpclient.impl.BasicHttpClientSecurityConfiguration;
+
+/**
+ * An initializer which initializes the global {@link HttpClientSecurityConfiguration}.
+ */
+public class HttpClientSecurityConfigurationInitalizer implements Initializer {
+
+    /** {@inheritDoc} */
+    public void init() throws InitializationException {
+        // This is empty, just need to register it to satisfy resolver in case no others are supplied.
+        ConfigurationService.register(HttpClientSecurityConfiguration.class, new BasicHttpClientSecurityConfiguration());
+    }
+
+}
diff --git a/opensaml-security-impl/src/main/resources/META-INF/services/org.opensaml.core.config.Initializer b/opensaml-security-impl/src/main/resources/META-INF/services/org.opensaml.core.config.Initializer
index 3a2a150..9492c80 100644
--- a/opensaml-security-impl/src/main/resources/META-INF/services/org.opensaml.core.config.Initializer
+++ b/opensaml-security-impl/src/main/resources/META-INF/services/org.opensaml.core.config.Initializer
@@ -1 +1,2 @@
-org.opensaml.security.config.impl.ClientTLSValidationConfiguratonInitializer
\ No newline at end of file
+org.opensaml.security.config.impl.ClientTLSValidationConfiguratonInitializer
+org.opensaml.security.config.impl.HttpClientSecurityConfigurationInitalizer
\ No newline at end of file
diff --git a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java
index 757037a..c8fb849 100644
--- a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java
+++ b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java
@@ -21,12 +21,18 @@ import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.BaseContext;
 import org.opensaml.soap.client.SOAPClient.SOAPRequestParameters;
+import org.opensaml.soap.client.http.PipelineFactoryHttpSOAPClient;
+
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /** Message context for SOAP client messages. */
 public class SOAPClientContext extends BaseContext {
 
     /** Binding/transport-specific SOAP request parameters. */
-    private SOAPRequestParameters requestParameters;
+    @Nullable private SOAPRequestParameters requestParameters;
+    
+    /** Name of the specific SOAP client pipeline to use, for example with {@link PipelineFactoryHttpSOAPClient}. */
+    @Nullable private String pipelineName;
 
     /**
      * Gets a set of binding/transport-specific request parameters.
@@ -46,4 +52,24 @@ public class SOAPClientContext extends BaseContext {
         requestParameters = parameters;
     }
 
+    /**
+     * Get the name of the specific SOAP client message pipeline to use, 
+     * for example with {@link PipelineFactoryHttpSOAPClient}. 
+     * 
+     * @return the pipeline name, or null
+     */
+    @Nullable public String getPipelineName() {
+        return pipelineName;
+    }
+
+    /**
+     * Set the name of the specific SOAP client message pipeline to use, 
+     * for example with {@link PipelineFactoryHttpSOAPClient}. 
+     * 
+     * @param name the pipeline name, or null
+     */
+    public void setPipelineName(@Nullable final String name) {
+        pipelineName = StringSupport.trimOrNull(name);
+    }
+
 }
\ No newline at end of file
diff --git a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/http/PipelineFactoryHttpSOAPClient.java b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/http/PipelineFactoryHttpSOAPClient.java
index 96d2904..a511d87 100644
--- a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/http/PipelineFactoryHttpSOAPClient.java
+++ b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/http/PipelineFactoryHttpSOAPClient.java
@@ -21,19 +21,20 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
 
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.logic.Constraint;
-
 import org.opensaml.messaging.context.InOutOperationContext;
 import org.opensaml.messaging.pipeline.httpclient.HttpClientMessagePipeline;
 import org.opensaml.messaging.pipeline.httpclient.HttpClientMessagePipelineFactory;
+import org.opensaml.soap.client.SOAPClientContext;
 import org.opensaml.soap.common.SOAPException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
 
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
 /**
  * SOAP client that is based on {@link HttpClientMessagePipeline}, produced at runtime from an instance of
  * {@link HttpClientMessagePipelineFactory}.
@@ -86,6 +87,10 @@ public class PipelineFactoryHttpSOAPClient<OutboundMessageType, InboundMessageTy
         if (pipelineFactory == null) {
             throw new ComponentInitializationException("HttpClientPipelineFactory cannot be null");
         } 
+        
+        if (pipelineNameStrategy == null) {
+            pipelineNameStrategy = new DefaultPipelineNameStrategy();
+        }
     }
 
     /** {@inheritDoc} */
@@ -189,5 +194,27 @@ public class PipelineFactoryHttpSOAPClient<OutboundMessageType, InboundMessageTy
             return null;
         }
     }
+    
+    
+    /**
+     * Default strategy for resolving SOAP client message pipeline name from the 
+     * {@link SOAPClientContext#getPipelineName()} which is a direct child of the input operation context.
+     */
+    public static class DefaultPipelineNameStrategy implements Function<InOutOperationContext<?,?>, String> {
+
+        /** {@inheritDoc} */
+        public String apply(@Nullable final InOutOperationContext<?, ?> opContext) {
+            if (opContext == null) {
+                return null;
+            }
+            final SOAPClientContext context = opContext.getSubcontext(SOAPClientContext.class);
+            if (context != null) {
+                return context.getPipelineName();
+            } else {
+                return null;
+            }
+        }
+        
+    }
 
 }
diff --git a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityContext.java
similarity index 53%
copy from opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java
copy to opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityContext.java
index 757037a..01013ba 100644
--- a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/SOAPClientContext.java
+++ b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityContext.java
@@ -15,35 +15,36 @@
  * limitations under the License.
  */
 
-package org.opensaml.soap.client;
+package org.opensaml.soap.client.security;
 
 import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.BaseContext;
-import org.opensaml.soap.client.SOAPClient.SOAPRequestParameters;
 
-/** Message context for SOAP client messages. */
-public class SOAPClientContext extends BaseContext {
-
-    /** Binding/transport-specific SOAP request parameters. */
-    private SOAPRequestParameters requestParameters;
+/**
+ * Context class for holding security information related to SOAP client operations.
+ */
+public class SOAPClientSecurityContext extends BaseContext {
+    
+    /** Security configuration profile ID. */
+    @Nullable private String securityConfigurationProfileId;
 
     /**
-     * Gets a set of binding/transport-specific request parameters.
-     *
-     * @return set of binding/transport-specific request parameters
+     * Get the security configuration profile ID.
+     * 
+     * @return the profile ID, or null
      */
-    @Nullable public SOAPRequestParameters getSOAPRequestParameters() {
-        return requestParameters;
+    @Nullable public String getSecurityConfigurationProfileId() {
+        return securityConfigurationProfileId;
     }
 
     /**
-     * Sets a set of binding/transport-specific request parameters.
-     *
-     * @param parameters a set of binding/transport-specific request parameters
+     * Set the security configuration profile ID.
+     * 
+     * @param profileId The profileID to set
      */
-    public void setSOAPRequestParameters(@Nullable final SOAPRequestParameters parameters) {
-        requestParameters = parameters;
+    public void setSecurityConfigurationProfileId(@Nullable final String profileId) {
+        securityConfigurationProfileId = profileId;
     }
 
-}
\ No newline at end of file
+}
diff --git a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityProfileIdLookupFunction.java b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityProfileIdLookupFunction.java
new file mode 100644
index 0000000..f30d1c1
--- /dev/null
+++ b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/SOAPClientSecurityProfileIdLookupFunction.java
@@ -0,0 +1,76 @@
+/*
+ * 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.soap.client.security;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.InOutOperationContext;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * Function to resolve SOAP client security profile ID from message context.
+ */
+public class SOAPClientSecurityProfileIdLookupFunction implements ContextDataLookupFunction<MessageContext, String> {
+    
+    /** Lookup function for {@link SOAPClientSecurityContext. */
+    private Function<MessageContext, SOAPClientSecurityContext> soapContextLookup;
+    
+    /**
+     * Constructor.
+     */
+    public SOAPClientSecurityProfileIdLookupFunction() {
+        soapContextLookup = Functions.compose(
+                new ChildContextLookup<>(SOAPClientSecurityContext.class),
+                new RecursiveTypedParentContextLookup(InOutOperationContext.class)
+                );
+    }
+    
+    /**
+     * Set lookup function for for {@link SOAPClientSecurityContext}.
+     * 
+     * @param lookup the lookup function
+     */
+    public void setSOAPClientSecurityContextLookup(
+            @Nonnull final Function<MessageContext, SOAPClientSecurityContext> lookup) {
+       soapContextLookup = Constraint.isNotNull(lookup, "SOAPClientSecurityContext lookup function was null") ;
+    }
+
+    /** {@inheritDoc} */
+    public String apply(@Nullable final MessageContext messageContext) {
+        if (messageContext == null) {
+            return null;
+        }
+        
+        final SOAPClientSecurityContext context = soapContextLookup.apply(messageContext);
+        if (context != null) {
+            return context.getSecurityConfigurationProfileId();
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/package-info.java b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/package-info.java
new file mode 100644
index 0000000..d5e0b55
--- /dev/null
+++ b/opensaml-soap-api/src/main/java/org/opensaml/soap/client/security/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+/** Classes related to SOAP client security. */
+package org.opensaml.soap.client.security;
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list