[java-identity-provider] branch master updated: IDP-1511 - Support referencing of non-inline MetadataFilters
Scott Cantor
cantor.2 at osu.edu
Tue Oct 22 11:05:51 EDT 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=3c9ba87764042eb16fb767c04f70b2c896ce33a5
The following commit(s) were added to refs/heads/master by this push:
new 3c9ba87 IDP-1511 - Support referencing of non-inline MetadataFilters
3c9ba87 is described below
commit 3c9ba87764042eb16fb767c04f70b2c896ce33a5
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Oct 22 11:05:47 2019 -0400
IDP-1511 - Support referencing of non-inline MetadataFilters
https://issues.shibboleth.net/jira/browse/IDP-1511
Implementation through a bridging component installed
with a BeanPostProcessor.
---
.../system/conf/metadata-providers-system.xml | 7 +-
.../main/resources/system/conf/services-system.xml | 10 +--
...stEnvironmentApplicationContextInitializer.java | 2 +
idp-conf/src/test/resources/conf/global.xml | 6 ++
...metadata-providers.xml => metadata-filters.xml} | 41 ++-------
.../src/test/resources/conf/metadata-providers.xml | 24 ++----
.../metadata/AbstractMetadataProviderParser.java | 13 ++-
.../metadata/filter/impl/ByReferenceParser.java | 94 +++++++++++++++++++++
.../impl/ByReferenceFilterBeanPostProcessor.java | 97 ++++++++++++++++++++++
.../metadata/impl/MetadataNamespaceHandler.java | 2 +
.../NodeProcessingAttachingBeanPostProcessor.java | 8 +-
.../impl/ByReferenceMetadataFilterBridge.java | 89 ++++++++++++++++++++
.../main/resources/schema/shibboleth-metadata.xsd | 26 ++++++
13 files changed, 351 insertions(+), 68 deletions(-)
diff --git a/idp-conf/src/main/resources/system/conf/metadata-providers-system.xml b/idp-conf/src/main/resources/system/conf/metadata-providers-system.xml
index 55775cb..c54996a 100644
--- a/idp-conf/src/main/resources/system/conf/metadata-providers-system.xml
+++ b/idp-conf/src/main/resources/system/conf/metadata-providers-system.xml
@@ -12,7 +12,12 @@
default-init-method="initialize"
default-destroy-method="destroy">
- <!-- Beans internal to metadata configuration but not for user manipulation. -->
+ <!-- BeanPostProcessors that auto-install MetadataFilters for internal use. -->
+
+ <bean class="net.shibboleth.idp.profile.spring.relyingparty.metadata.impl.ByReferenceFilterBeanPostProcessor" />
+
+ <bean class="net.shibboleth.idp.profile.spring.relyingparty.metadata.impl.NodeProcessingAttachingBeanPostProcessor"
+ c:service-ref="shibboleth.AttributeRegistryService" />
<!-- Signature Validation Criteria -->
diff --git a/idp-conf/src/main/resources/system/conf/services-system.xml b/idp-conf/src/main/resources/system/conf/services-system.xml
index 3950fcb..1cc2546 100644
--- a/idp-conf/src/main/resources/system/conf/services-system.xml
+++ b/idp-conf/src/main/resources/system/conf/services-system.xml
@@ -101,18 +101,12 @@
p:serviceConfigurations-ref="#{'%{idp.service.metadata.resources:shibboleth.MetadataResolverResources}'.trim()}"
p:failFast="%{idp.service.metadata.failFast:%{idp.service.failFast:false}}"
p:reloadCheckDelay="%{idp.service.metadata.checkInterval:PT0S}"
- p:beanFactoryPostProcessors-ref="shibboleth.PropertySourcesPlaceholderConfigurer">
+ p:beanFactoryPostProcessors-ref="shibboleth.PropertySourcesPlaceholderConfigurer"
+ p:beanPostProcessors-ref="shibboleth.IdentifiableBeanPostProcessor">
<constructor-arg name="claz" value="org.opensaml.saml.metadata.resolver.MetadataResolver" />
<constructor-arg name="strategy">
<bean class="net.shibboleth.idp.profile.spring.relyingparty.metadata.impl.MetadataResolverServiceStrategy" />
</constructor-arg>
- <property name="beanPostProcessors">
- <list>
- <ref bean="shibboleth.IdentifiableBeanPostProcessor" />
- <bean class="net.shibboleth.idp.profile.spring.relyingparty.metadata.impl.NodeProcessingAttachingBeanPostProcessor"
- c:service-ref="shibboleth.AttributeRegistryService" />
- </list>
- </property>
</bean>
<bean id="shibboleth.ReloadableAccessControlService" class="net.shibboleth.ext.spring.service.ReloadableSpringService"
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/TestEnvironmentApplicationContextInitializer.java b/idp-conf/src/test/java/net/shibboleth/idp/test/TestEnvironmentApplicationContextInitializer.java
index e57637d..44fa18e 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/TestEnvironmentApplicationContextInitializer.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/TestEnvironmentApplicationContextInitializer.java
@@ -51,7 +51,9 @@ public class TestEnvironmentApplicationContextInitializer
mock.setProperty("idp.storage.htmlLocalStorage", "false");
mock.setProperty("idp.session.trackSPSessions", "false");
mock.setProperty("idp.session.secondaryServiceIndex", "false");
+ mock.setProperty("idp.service.metadata.resources", "testbed.MetadataResolverResources");
applicationContext.getEnvironment().getPropertySources().addFirst(mock);
log.info("Prepending properties '{}'", mock.getSource());
}
+
}
\ No newline at end of file
diff --git a/idp-conf/src/test/resources/conf/global.xml b/idp-conf/src/test/resources/conf/global.xml
index dcbc143..7b79f7a 100644
--- a/idp-conf/src/test/resources/conf/global.xml
+++ b/idp-conf/src/test/resources/conf/global.xml
@@ -68,4 +68,10 @@
<constructor-arg value="/metadata/example-sp123-metadata.xml"/>
</bean>
+ <util:list id="testbed.MetadataResolverResources">
+ <value>%{idp.home}/conf/metadata-providers.xml</value>
+ <value>%{idp.home}/conf/metadata-filters.xml</value>
+ <value>%{idp.home}/system/conf/metadata-providers-system.xml</value>
+ </util:list>
+
</beans>
diff --git a/idp-conf/src/test/resources/conf/metadata-providers.xml b/idp-conf/src/test/resources/conf/metadata-filters.xml
similarity index 54%
copy from idp-conf/src/test/resources/conf/metadata-providers.xml
copy to idp-conf/src/test/resources/conf/metadata-filters.xml
index 3e687ba..9a16b61 100644
--- a/idp-conf/src/test/resources/conf/metadata-providers.xml
+++ b/idp-conf/src/test/resources/conf/metadata-filters.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"
+<MetadataFilter xsi:type="ByReference"
xmlns="urn:mace:shibboleth:2.0:metadata"
xmlns:security="urn:mace:shibboleth:2.0:security"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
@@ -19,30 +19,9 @@
http://www.w3.org/2009/xmldsig11# http://www.w3.org/TR/2013/REC-xmldsig-core1-20130411/xmldsig11-schema.xsd
http://www.w3.org/2001/04/xmlenc# http://www.w3.org/TR/xmlenc-core/xenc-schema.xsd
http://www.w3.org/2009/xmlenc11# http://www.w3.org/TR/2013/REC-xmlenc-core1-20130411/xenc-schema-11.xsd">
-
- <!-- ========================================== -->
- <!-- Metadata Configuration -->
- <!-- ========================================== -->
- <!-- Example metadata provider. -->
-
- <MetadataProvider id="URLMD" xsi:type="ResourceBackedMetadataProvider" maxRefreshDelay="PT5M" indexesRef="testbed.MetadataIndexes" resourceRef="exampleMetadata">
- <MetadataFilter xsi:type="SignatureValidation" requireSignedRoot="false"> <!-- TODO -->
- <PublicKey>
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
- uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
- LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
- NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
- nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
- E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
- 4wIDAQAB
- </PublicKey>
- </MetadataFilter>
- <MetadataFilter xsi:type="SchemaValidation"/>
- <MetadataFilter xsi:type="EntityRoleWhiteList">
- <RetainedRole>md:SPSSODescriptor</RetainedRole>
- </MetadataFilter>
-
+ <MetadataFilters providerRef="URLMD">
+
<MetadataFilter xsi:type="EntityAttributes">
<saml:Attribute Name="https://sp.example.org/tagname">
<saml:AttributeValue>foo</saml:AttributeValue>
@@ -58,16 +37,6 @@
<Entity>https://sp.example.org</Entity>
</MetadataFilter>
- <MetadataFilter xsi:type="Algorithm">
- <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep">
- <MGF xmlns="http://www.w3.org/2009/xmlenc11#"
- Algorithm="http://www.w3.org/2009/xmlenc11#mgf1sha256" />
- <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
- Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
- </md:EncryptionMethod>
- <Entity>https://sp.example.org</Entity>
- </MetadataFilter>
- </MetadataProvider>
+ </MetadataFilters>
- <MetadataProvider id="SP123MD" xsi:type="ResourceBackedMetadataProvider" maxRefreshDelay="PT5M" indexesRef="testbed.MetadataIndexes" resourceRef="exampleMetadata-sp123"/>
-</MetadataProvider>
+</MetadataFilter>
diff --git a/idp-conf/src/test/resources/conf/metadata-providers.xml b/idp-conf/src/test/resources/conf/metadata-providers.xml
index 3e687ba..2df93e0 100644
--- a/idp-conf/src/test/resources/conf/metadata-providers.xml
+++ b/idp-conf/src/test/resources/conf/metadata-providers.xml
@@ -43,21 +43,6 @@
<RetainedRole>md:SPSSODescriptor</RetainedRole>
</MetadataFilter>
- <MetadataFilter xsi:type="EntityAttributes">
- <saml:Attribute Name="https://sp.example.org/tagname">
- <saml:AttributeValue>foo</saml:AttributeValue>
- </saml:Attribute>
- <saml:Attribute Name="https://sp.example.org/tagname2">
- <saml:AttributeValue>foo</saml:AttributeValue>
- <saml:AttributeValue>bar</saml:AttributeValue>
- </saml:Attribute>
- <saml:Attribute Name="http://shibboleth.net/ns/profiles/saml1/sso/browser/includeAttributeStatement"
- NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
- <saml:AttributeValue>1</saml:AttributeValue>
- </saml:Attribute>
- <Entity>https://sp.example.org</Entity>
- </MetadataFilter>
-
<MetadataFilter xsi:type="Algorithm">
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep">
<MGF xmlns="http://www.w3.org/2009/xmlenc11#"
@@ -70,4 +55,13 @@
</MetadataProvider>
<MetadataProvider id="SP123MD" xsi:type="ResourceBackedMetadataProvider" maxRefreshDelay="PT5M" indexesRef="testbed.MetadataIndexes" resourceRef="exampleMetadata-sp123"/>
+
+ <!--
+ <MetadataProvider id="ICMDQ" xsi:type="DynamicHTTPMetadataProvider"
+ minCacheDuration="PT5M" maxCacheDuration="PT24H" maxIdleEntityData="PT1H">
+ <MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D" />
+ <MetadataQueryProtocol>https://mdq.incommon.org/</MetadataQueryProtocol>
+ </MetadataProvider>
+ -->
+
</MetadataProvider>
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataProviderParser.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataProviderParser.java
index f93eff9..8801368 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataProviderParser.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataProviderParser.java
@@ -187,11 +187,10 @@ public abstract class AbstractMetadataProviderParser extends AbstractSingleBeanD
processPredicateOptions(element, parserContext, builder);
- if (!isChaining(element)) {
- final List<Element> filters =
- ElementSupport.getChildElements(element, METADATA_FILTER_ELEMENT_NAME);
-
- if (null != filters) {
+ final List<Element> filters =
+ ElementSupport.getChildElements(element, METADATA_FILTER_ELEMENT_NAME);
+ if (null != filters && !filters.isEmpty()) {
+ if (!isChaining(element)) {
if (filters.size() == 1) {
// Install directly.
builder.addPropertyValue("metadataFilter",
@@ -204,9 +203,9 @@ public abstract class AbstractMetadataProviderParser extends AbstractSingleBeanD
chainBuilder));
builder.addPropertyValue("metadataFilter", chainBuilder.getBeanDefinition());
}
+ } else {
+ log.warn("MetadataFilter is not valid for {}", CHAINING_PROVIDER_ELEMENT_NAME.getLocalPart());
}
- } else {
- log.warn("MetadataFilter is not valid for {}", CHAINING_PROVIDER_ELEMENT_NAME.getLocalPart());
}
}
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/ByReferenceParser.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/ByReferenceParser.java
new file mode 100644
index 0000000..b863b20
--- /dev/null
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/ByReferenceParser.java
@@ -0,0 +1,94 @@
+/*
+ * 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 net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.idp.profile.spring.relyingparty.metadata.AbstractMetadataProviderParser;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.opensaml.saml.metadata.resolver.filter.impl.ByReferenceMetadataFilter;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for a <ByReference> filter.
+ */
+public class ByReferenceParser extends AbstractSingleBeanDefinitionParser {
+
+ /** Element name. */
+ @Nonnull public static final QName TYPE_NAME =
+ new QName(AbstractMetadataProviderParser.METADATA_NAMESPACE, "ByReference");
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return ByReferenceMetadataFilter.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+ builder.setLazyInit(false);
+
+ final List<Element> children = ElementSupport.getChildElements(element,
+ new QName(AbstractMetadataProviderParser.METADATA_NAMESPACE, "MetadataFilters"));
+
+ if (null != children && !children.isEmpty()) {
+
+ final ManagedMap<Object,BeanDefinition> mappings = new ManagedMap<>();
+
+ for (final Element child : children) {
+ final List<Element> filters = ElementSupport.getChildElements(child,
+ new QName(AbstractMetadataProviderParser.METADATA_NAMESPACE, "MetadataFilter"));
+ if (filters != null && !filters.isEmpty()) {
+ final String providerRef = child.getAttributeNS(null, "providerRef");
+ final ManagedList<BeanDefinition> filterBeans =
+ SpringSupport.parseCustomElements(filters, parserContext, builder);
+ if (filterBeans != null) {
+ if (filterBeans.size() == 1) {
+ mappings.put(providerRef, filterBeans.get(0));
+ } else {
+ final BeanDefinitionBuilder chain =
+ BeanDefinitionBuilder.genericBeanDefinition(MetadataFilterChain.class);
+ chain.addPropertyValue("filters", filterBeans);
+ mappings.put(providerRef, chain.getBeanDefinition());
+ }
+ }
+ }
+ }
+
+ builder.addPropertyValue("filterMappings", mappings);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected boolean shouldGenerateId() {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/ByReferenceFilterBeanPostProcessor.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/ByReferenceFilterBeanPostProcessor.java
new file mode 100644
index 0000000..f2e6aa2
--- /dev/null
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/ByReferenceFilterBeanPostProcessor.java
@@ -0,0 +1,97 @@
+/*
+ * 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 net.shibboleth.idp.profile.spring.relyingparty.metadata.impl;
+
+import java.util.Arrays;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+import net.shibboleth.idp.saml.metadata.impl.ByReferenceMetadataFilterBridge;
+
+/**
+ * A {@link BeanPostProcessor} for {@link MetadataResolver} beans that ensures a {@link ByReferenceMetadataFilterBridge}
+ * is attached.
+ */
+public class ByReferenceFilterBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, Ordered {
+
+ /** Spring context. */
+ @Nullable private ApplicationContext applicationContext;
+
+ /** {@inheritDoc} */
+ public int getOrder() {
+ return HIGHEST_PRECEDENCE;
+ }
+
+ /** {@inheritDoc} */
+ public void setApplicationContext(@Nullable final ApplicationContext context) throws BeansException {
+ applicationContext = context;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
+ if (!(bean instanceof MetadataResolver) || bean instanceof ChainingMetadataResolver) {
+ // Do not attach to beans which just include other ones.
+ return bean;
+ }
+
+ final MetadataResolver resolver = (MetadataResolver) bean;
+
+ boolean filterAttached = false;
+
+ final MetadataFilter filter = resolver.getMetadataFilter();
+ if (filter instanceof ByReferenceMetadataFilterBridge) {
+ filterAttached = true;
+ } else if (filter instanceof MetadataFilterChain) {
+ filterAttached = ((MetadataFilterChain) filter).getFilters().stream().anyMatch(
+ f -> f instanceof ByReferenceMetadataFilterBridge);
+ }
+
+ if (!filterAttached) {
+ final ByReferenceMetadataFilterBridge filterToAttach = new ByReferenceMetadataFilterBridge();
+ filterToAttach.setApplicationContext(applicationContext);
+
+ if (filter == null) {
+ resolver.setMetadataFilter(filterToAttach);
+ } else if (filter instanceof MetadataFilterChain) {
+ ((MetadataFilterChain) filter).getFilters().add(filterToAttach);
+ } else {
+ final MetadataFilterChain chain = new MetadataFilterChain();
+ chain.setFilters(Arrays.asList(filter, filterToAttach));
+ resolver.setMetadataFilter(chain);
+ }
+ }
+
+ return resolver;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object postProcessAfterInitialization(final Object bean, final String beanName) {
+ return bean;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/MetadataNamespaceHandler.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/MetadataNamespaceHandler.java
index 00cefbe..09ce2f1 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/MetadataNamespaceHandler.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/MetadataNamespaceHandler.java
@@ -22,6 +22,7 @@ import javax.xml.namespace.QName;
import net.shibboleth.ext.spring.util.BaseSpringNamespaceHandler;
import net.shibboleth.idp.profile.spring.relyingparty.metadata.AbstractMetadataProviderParser;
import net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl.AlgorithmFilterParser;
+import net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl.ByReferenceParser;
import net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl.EntitiesDescriptorNameParser;
import net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl.EntityAttributesFilterParser;
import net.shibboleth.idp.profile.spring.relyingparty.metadata.filter.impl.EntityRoleFilterParser;
@@ -71,6 +72,7 @@ public class MetadataNamespaceHandler extends BaseSpringNamespaceHandler {
registerBeanDefinitionParser(SchemaValidationParser.TYPE_NAME, new SchemaValidationParser());
registerBeanDefinitionParser(SignatureValidationParser.TYPE_NAME, new SignatureValidationParser());
registerBeanDefinitionParser(NodeProcessingParser.TYPE_NAME, new NodeProcessingParser());
+ registerBeanDefinitionParser(ByReferenceParser.TYPE_NAME, new ByReferenceParser());
// Node Processors
registerBeanDefinitionParser(EntitiesDescriptorNameParser.TYPE_NAME, new EntitiesDescriptorNameParser());
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/NodeProcessingAttachingBeanPostProcessor.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/NodeProcessingAttachingBeanPostProcessor.java
index 9cbf430..833318c 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/NodeProcessingAttachingBeanPostProcessor.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/impl/NodeProcessingAttachingBeanPostProcessor.java
@@ -32,6 +32,7 @@ import org.opensaml.saml.metadata.resolver.filter.impl.EntitiesDescriptorNamePro
import org.opensaml.saml.metadata.resolver.filter.impl.NodeProcessingMetadataFilter;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.Ordered;
import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
import net.shibboleth.idp.saml.metadata.impl.AttributeMappingNodeProcessor;
@@ -51,7 +52,7 @@ import net.shibboleth.utilities.java.support.service.ReloadableService;
* depend on group information.
* </p>
*/
-public class NodeProcessingAttachingBeanPostProcessor implements BeanPostProcessor {
+public class NodeProcessingAttachingBeanPostProcessor implements BeanPostProcessor, Ordered {
/** The registry of decoding rules. */
@Nullable private final ReloadableService<AttributeTranscoderRegistry> transcoderRegistry;
@@ -66,6 +67,11 @@ public class NodeProcessingAttachingBeanPostProcessor implements BeanPostProcess
transcoderRegistry = service;
}
+ /** {@inheritDoc} */
+ public int getOrder() {
+ return LOWEST_PRECEDENCE;
+ }
+
// Checkstyle: CyclomaticComplexity OFF
/** {@inheritDoc} */
@Override public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ByReferenceMetadataFilterBridge.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ByReferenceMetadataFilterBridge.java
new file mode 100644
index 0000000..8f0034d
--- /dev/null
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ByReferenceMetadataFilterBridge.java
@@ -0,0 +1,89 @@
+/*
+ * 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 net.shibboleth.idp.saml.metadata.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.saml.metadata.resolver.filter.FilterException;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
+import org.opensaml.saml.metadata.resolver.filter.impl.ByReferenceMetadataFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * This is a bridge filter that uses Spring to locate extant {@link ByReferenceMetadataFilter}
+ * objects to run.
+ */
+public class ByReferenceMetadataFilterBridge implements MetadataFilter {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ByReferenceMetadataFilterBridge.class);
+
+ /** Application context. */
+ @Nullable private ApplicationContext applicationContext;
+
+ /** Chain to wrap the beans obtained from the context. */
+ @Nullable private MetadataFilterChain filterChain;
+
+ /**
+ * Set the containing {@link ApplicationContext}.
+ *
+ * @param context the context
+ */
+ public void setApplicationContext(@Nullable final ApplicationContext context) {
+ applicationContext = context;
+ }
+
+ /** {@inheritDoc} */
+ public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
+ throws FilterException {
+
+ MetadataFilterChain chain = null;
+
+ synchronized(this) {
+ if (filterChain != null) {
+ chain = filterChain;
+ } else if (applicationContext != null) {
+ try {
+ final Map<String,ByReferenceMetadataFilter> beans =
+ applicationContext.getBeansOfType(ByReferenceMetadataFilter.class);
+ log.debug("Bridging to {} ByReference filters in Spring context", beans.size());
+ filterChain = new MetadataFilterChain();
+ filterChain.setFilters(List.copyOf(beans.values()));
+ chain = filterChain;
+ } catch (final BeansException e) {
+ throw new FilterException(e);
+ }
+ } else {
+ throw new FilterException("ApplicationContext is not set");
+ }
+ }
+
+ return chain != null ? chain.filter(metadata, context) : metadata;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd b/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
index 7e47a90..082fc59 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
@@ -1254,6 +1254,32 @@
</complexContent>
</complexType>
+ <complexType name="ByReference">
+ <annotation>
+ <documentation>
+ A metadata filter that associates filters declared "out of band" with specific
+ MetadataProvider instances.
+ </documentation>
+ </annotation>
+ <complexContent>
+ <extension base="shibmd:MetadataFilterType">
+ <sequence>
+ <element name="MetadataFilters" minOccurs="0" maxOccurs="unbounded">
+ <annotation>
+ <documentation>A set of filters applied to a specific provider by name.</documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="shibmd:MetadataFilter" minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <attribute name="providerRef" type="shibmd:string" use="required" />
+ </complexType>
+ </element>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
<complexType name="MetadataFilterType" abstract="true"/>
<element name="MetadataNodeProcessor" type="shibmd:MetadataNodeProcessorType">
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list