[java-shib-attribute] branch main updated: IDP-2152 - DataConnector for metadata tags
Scott Cantor
cantor.2 at osu.edu
Tue Aug 8 15:00:06 UTC 2023
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-shib-attribute.
View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=77332971d644dce6c05b03b75e2ae8a6b610691d
The following commit(s) were added to refs/heads/main by this push:
new 77332971d IDP-2152 - DataConnector for metadata tags
77332971d is described below
commit 77332971d644dce6c05b03b75e2ae8a6b610691d
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Aug 8 11:00:03 2023 -0400
IDP-2152 - DataConnector for metadata tags
https://shibboleth.atlassian.net/browse/IDP-2152
Initial implementation pending testing.
---
.../impl/EntityAttributesDataConnectorParser.java | 59 ++++++++++
.../impl/AttributeResolverNamespaceHandler.java | 4 +-
.../schema/shibboleth-attribute-resolver.xsd | 23 +++-
.../impl/EntityAttributesDataConnector.java | 131 +++++++++++++++++++++
4 files changed, 213 insertions(+), 4 deletions(-)
diff --git a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/EntityAttributesDataConnectorParser.java b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/EntityAttributesDataConnectorParser.java
new file mode 100644
index 000000000..55de010c2
--- /dev/null
+++ b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/impl/EntityAttributesDataConnectorParser.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed 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 net.shibboleth.idp.attribute.resolver.spring.dc.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import net.shibboleth.idp.attribute.resolver.spring.dc.AbstractDataConnectorParser;
+import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
+import net.shibboleth.idp.saml.attribute.resolver.impl.EntityAttributesDataConnector;
+import net.shibboleth.shared.xml.AttributeSupport;
+
+/** Bean definition Parser for a {@link EntityAttributesDataConnector}. */
+public class EntityAttributesDataConnectorParser extends AbstractDataConnectorParser {
+
+ /** Schema type - resolver. */
+ @Nonnull public static final QName TYPE_NAME =
+ new QName(AttributeResolverNamespaceHandler.NAMESPACE, "EntityAttributes");
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable protected final Class<EntityAttributesDataConnector> getBeanClass(@Nonnull final Element element) {
+ return EntityAttributesDataConnector.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
+ @Nonnull final BeanDefinitionBuilder builder) {
+ super.doParse(config, parserContext, builder);
+
+ if (config.hasAttributeNS(null, "metadataContextStrategyRef")) {
+ builder.addPropertyReference("metadataContextLookupStrategy",
+ AttributeSupport.ensureAttributeValue(config, null, "metadataContextStrategyRef"));
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected boolean failOnDependencies() {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
index f235fdf07..623bd7133 100644
--- a/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
+++ b/shib-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverNamespaceHandler.java
@@ -120,8 +120,8 @@ public class AttributeResolverNamespaceHandler extends BaseSpringNamespaceHandle
registerBeanDefinitionParser(SubjectDataConnectorParser.TYPE_NAME, new SubjectDataConnectorParser());
registerBeanDefinitionParser(StorageServiceDataConnectorParser.TYPE_NAME,
new StorageServiceDataConnectorParser());
- //registerBeanDefinitionParser(EntityAttributesDataConnectorParser.TYPE_NAME,
- //new EntityAttributesDataConnectorParser());
+ registerBeanDefinitionParser(EntityAttributesDataConnectorParser.TYPE_NAME,
+ new EntityAttributesDataConnectorParser());
// Encoders
diff --git a/shib-attribute-resolver-spring/src/main/resources/schema/shibboleth-attribute-resolver.xsd b/shib-attribute-resolver-spring/src/main/resources/schema/shibboleth-attribute-resolver.xsd
index d03c8f5d4..4a61215a2 100644
--- a/shib-attribute-resolver-spring/src/main/resources/schema/shibboleth-attribute-resolver.xsd
+++ b/shib-attribute-resolver-spring/src/main/resources/schema/shibboleth-attribute-resolver.xsd
@@ -445,7 +445,7 @@
<complexType name="SAML1NameIdentifier">
<annotation>
- <documentation>An attribute definition that creates attributes whose values are SAML 1 NameIdentifiers.</documentation>
+ <documentation>DEPRECATED: An attribute definition that creates attributes whose values are SAML 1 NameIdentifiers.</documentation>
</annotation>
<complexContent>
<extension base="resolver:BaseAttributeDefinitionType">
@@ -472,7 +472,7 @@
<complexType name="SAML2NameID">
<annotation>
- <documentation>An attribute definition that creates attributes whose values are SAML 2 NameIDs.</documentation>
+ <documentation>DEPRECATED: An attribute definition that creates attributes whose values are SAML 2 NameIDs.</documentation>
</annotation>
<complexContent>
<extension base="resolver:BaseAttributeDefinitionType">
@@ -1753,6 +1753,25 @@
</complexContent>
</complexType>
+ <complexType name="EntityAttributes">
+ <annotation>
+ <documentation>
+ A connector for extracting mapped/decoded metadata tags from a peer's metadata.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="resolver:BaseDataConnectorType">
+ <attribute name="metadataContextStrategyRef" type="resolver:string">
+ <annotation>
+ <documentation>
+ Bean ID of a Function to locate the SAMLMetadataContext to operate on.
+ Default is to locate it under the inbound message context via SAMLPeerEntityContext.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </complexContent>
+ </complexType>
<!-- Support types for DataConnectors -->
diff --git a/shib-saml-attribute-impl/src/main/java/net/shibboleth/idp/saml/attribute/resolver/impl/EntityAttributesDataConnector.java b/shib-saml-attribute-impl/src/main/java/net/shibboleth/idp/saml/attribute/resolver/impl/EntityAttributesDataConnector.java
new file mode 100644
index 000000000..3e3ee3294
--- /dev/null
+++ b/shib-saml-attribute-impl/src/main/java/net/shibboleth/idp/saml/attribute/resolver/impl/EntityAttributesDataConnector.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed 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 net.shibboleth.idp.saml.attribute.resolver.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
+import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+import org.opensaml.saml.ext.saml2mdattr.EntityAttributes;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Multimap;
+
+import net.shibboleth.idp.attribute.AttributesMapContainer;
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.resolver.AbstractDataConnector;
+import net.shibboleth.idp.attribute.resolver.DataConnector;
+import net.shibboleth.idp.attribute.resolver.ResolutionException;
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolverWorkContext;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * A {@link DataConnector} that returns the decoded {@link EntityAttributes}
+ * from a peer's metadata.
+ *
+ * @since 5.0.0
+ */
+ at ThreadSafe
+public class EntityAttributesDataConnector extends AbstractDataConnector {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(EntityAttributesDataConnector.class);
+
+ /** Metadata context lookup strategy. */
+ @Nonnull private Function<ProfileRequestContext,SAMLMetadataContext> metadataContextLookupStrategy;
+
+ /** Constructor. */
+ public EntityAttributesDataConnector() {
+ // Default is inbound -> SAMLPeerEntityContext -> SAMLMetadataContext.
+ metadataContextLookupStrategy = new ChildContextLookup<>(SAMLMetadataContext.class).compose(
+ new ChildContextLookup<>(SAMLPeerEntityContext.class).compose(
+ new InboundMessageContextLookup()));
+ }
+
+ /**
+ * Set the lookup strategy for the {@link SAMLMetadataContext} to pull tags from.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMetadataContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,SAMLMetadataContext> strategy) {
+ metadataContextLookupStrategy = Constraint.isNotNull(strategy, "SAMLMetadataContext strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull @Unmodifiable @NotLive protected Map<String, IdPAttribute> doDataConnectorResolve(
+ @Nonnull final AttributeResolutionContext resolutionContext,
+ @Nonnull final AttributeResolverWorkContext workContext) throws ResolutionException {
+
+ final SAMLMetadataContext metadataContext = metadataContextLookupStrategy.apply(
+ resolutionContext.getProfileRequestContextLookupStrategy().apply(resolutionContext));
+ final EntityDescriptor entity = metadataContext != null ? metadataContext.getEntityDescriptor() : null;
+ if (entity == null) {
+ log.debug("Specified metadata source was absent.");
+ return CollectionSupport.emptyMap();
+ }
+
+ final List<AttributesMapContainer> containerList = entity.getObjectMetadata().get(AttributesMapContainer.class);
+ if (containerList != null && !containerList.isEmpty()) {
+ final AttributesMapContainer container = containerList.get(0);
+ final Multimap<String,IdPAttribute> tags = container.get();
+ if (!tags.isEmpty()) {
+ final Map<String,IdPAttribute> results = new HashMap<>();
+
+ for (final IdPAttribute attribute : tags.values()) {
+ try {
+ if (results.containsKey(attribute.getId())) {
+ final IdPAttribute existing = results.get(attribute.getId());
+ final List<IdPAttributeValue> union = new ArrayList<>(existing.getValues());
+ union.addAll(attribute.getValues());
+ existing.setValues(union);
+ } else {
+ // We have to clone because of the other branch of this conditional,
+ // we might need to mutate the values by combining them with a leter set.
+ results.put(attribute.getId(), attribute.clone());
+ }
+ } catch(final CloneNotSupportedException e) {
+ throw new ResolutionException(e);
+ }
+ }
+
+ log.trace("{} Resolved attributes: {}", getLogPrefix(), results);
+ return results;
+ }
+ }
+
+ log.trace("{} No entity attributes resolved", getLogPrefix());
+ return CollectionSupport.emptyMap();
+ }
+
+}
\ 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