[java-plugin-shibd] branch main updated: Initial wiring of CredentialResolver service and additional code.
Codeberg
noreply at shibboleth.net
Mon Jul 27 14:11:02 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/2638b7017dd36eaec0eb13a31eb70498e72d1c77
The following commit(s) were added to refs/heads/main by this push:
new 2638b70 Initial wiring of CredentialResolver service and additional code.
2638b70 is described below
commit 2638b7017dd36eaec0eb13a31eb70498e72d1c77
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Mon Jul 27 10:10:46 2026 -0400
Initial wiring of CredentialResolver service and additional code.
---
.../META-INF/net.shibboleth.idp/postconfig.xml | 37 ++++++++++++++--
.../shibboleth/idp/module/conf/sp/credentials.xml | 24 +++++++++++
.../shibboleth/idp/module/conf/sp/sp.properties | 8 +++-
.../net/shibboleth/sp/conf/agents-system.xml | 11 ++++-
.../net/shibboleth/sp/conf/credentials-system.xml | 24 +++++++++++
.../net/shibboleth/sp/conf/module.properties | 11 +++--
.../net/shibboleth/sp/service/utility.xml | 4 ++
.../AbstractOrderedCredentialResolver.java | 7 ++++
.../net/shibboleth/sp/credential/package-info.java | 18 ++++++++
.../sp/credential/impl/package-info.java | 18 ++++++++
.../net/shibboleth/sp/impl/BasicApplication.java | 49 ++++++++++++++++++++++
.../sp/security/config/impl/package-info.java | 18 ++++++++
12 files changed, 219 insertions(+), 10 deletions(-)
diff --git a/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index c74ed83..ebcf35b 100644
--- a/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -15,7 +15,7 @@
<!-- Agent reseolver service. -->
- <bean id="shibboleth.sp.AgentResolverService" parent="shibboleth.ReloadableService"
+ <bean id="shibboleth.sp.AgentResolverService" parent="shibboleth.ReloadableService"
c:claz="net.shibboleth.sp.impl.DefaultAgentResolver"
p:serviceConfigurations-ref="ExtendedAgentResolverResources"
p:failFast="%{sp.service.agents.failFast:%{idp.service.failFast:false}}"
@@ -24,7 +24,7 @@
<util:list id="shibboleth.sp.DefaultAgentResolverResources">
<value>conditional:%{idp.home}/conf/sp/agents.xml</value>
</util:list>
-
+
<!-- Auto-append system config files to resource set. -->
<bean id ="ExtendedAgentResolverResources" class="net.shibboleth.shared.spring.factory.CombiningListFactoryBean"
p:firstList="#{getObject('%{sp.service.agents.resources:shibboleth.sp.AgentResolverResources}'.trim()) ?:
@@ -35,12 +35,41 @@
</util:list>
</property>
</bean>
-
- <bean id="shibboleth.sp.metrics.AgentGaugeSet"
+
+ <bean id="shibboleth.sp.metrics.AgentResolverGaugeSet"
class="net.shibboleth.shared.service.ReloadableServiceGaugeSet" lazy-init="true"
c:metricName="net.shibboleth.sp.agent"
p:service-ref="shibboleth.sp.AgentResolverService" />
+
+ <!-- Credential resolver service. -->
+
+ <bean id="shibboleth.sp.CredentialResolverService" parent="shibboleth.ReloadableService"
+ c:claz="org.opensaml.security.credential.impl.ChainingCredentialResolver"
+ p:serviceConfigurations-ref="ExtendedCredentialResolverResources"
+ p:failFast="%{sp.service.credentials.failFast:%{idp.service.failFast:false}}"
+ p:reloadCheckDelay="%{sp.service.credentials.checkInterval:PT0S}" />
+ <util:list id="shibboleth.sp.DefaultCredentialResolverResources">
+ <value>conditional:%{idp.home}/conf/sp/credentials.xml</value>
+ </util:list>
+
+ <!-- Auto-append system config files to resource set. -->
+ <bean id ="ExtendedCredentialResolverResources" class="net.shibboleth.shared.spring.factory.CombiningListFactoryBean"
+ p:firstList="#{getObject('%{sp.service.credentials.resources:shibboleth.sp.CredentialResolverResources}'.trim()) ?:
+ getObject('shibboleth.sp.DefaultCredentialResolverResources')}">
+ <property name="secondList">
+ <util:list >
+ <value>classpath:/net/shibboleth/sp/conf/credentials-system.xml</value>
+ </util:list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.sp.metrics.CredentialResolverGaugeSet"
+ class="net.shibboleth.shared.service.ReloadableServiceGaugeSet" lazy-init="true"
+ c:metricName="net.shibboleth.sp.credential"
+ p:service-ref="shibboleth.sp.CredentialResolverService" />
+
+
<bean id="shibboleth.RemotedHttpServletRequestSupplier" class="net.shibboleth.sp.messaging.impl.RemotedHttpServletRequestSupplier" />
<bean id="shibboleth.RemotedHttpServletResponseSupplier" class="net.shibboleth.sp.messaging.impl.RemotedlHttpServletResponseSupplier" />
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/credentials.xml b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/credentials.xml
new file mode 100644
index 0000000..ee50782
--- /dev/null
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/credentials.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!--
+ Protocol plugins will typically auto-install "default" credentials for simple
+ deployments to use. When supporting multiple Agents, migrating systems with
+ existing keys, or simply where required, this file provides a built-in location
+ to define additional keys, certificates, secrets, etc.
+
+ Refer to protocol-specific documentation for how to use this file.
+ -->
+
+</beans>
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
index 377f5e8..c33cd39 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
@@ -4,7 +4,7 @@ sp.issuer = https://sp.example.org
# Default authentication authority (IdP, OP, etc.) to use if any
#sp.defaultAuthority = https://idp.example.org
-# Controls configuration of service to resolve SP agents and applications
+# Configuration of service to resolve SP agents and applications
# Uncomment and define to override service resources
#sp.service.agents.resources = shibboleth.sp.AgentResolverResources
#sp.service.agents.failFast = false
@@ -12,6 +12,12 @@ sp.service.agents.checkInterval = PT5M
# Set to true for defaulted profile configs to be metadata-driven/aware
#sp.service.agents.useMetadataDrivenProfiles = false
+# Configuration of service to resolve SP credentials and secrets
+# Uncomment and define to override service resources
+#sp.service.credential.resources = shibboleth.sp.CredentialResolverResources
+#sp.service.credential.failFast = false
+sp.service.credential.checkInterval = PT5M
+
# General SP cookie properties
#sp.cookie.secure = true
#sp.cookie.httpOnly = true
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
index 8a29b29..a71ce38 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
@@ -62,7 +62,8 @@
p:unverifiedConfiguration-ref="DefaultUnverifiedRelyingPartyConfiguration"
p:relyingPartyConfigurations-ref="shibboleth.sp.RelyingPartyOverrides"
p:discoveryServiceLookupStrategy="#{getObject('%{sp.discoveryURLFunction:DefaultDiscoveryServiceStrategy}'.trim())}"
- p:stateManager-ref="#{'%{sp.stateToken.Manager:shibboleth.sp.CookieStateManager}'.trim()}" />
+ p:stateManager-ref="#{'%{sp.stateToken.Manager:shibboleth.sp.CookieStateManager}'.trim()}"
+ p:credentialResolver-ref="shibboleth.sp.CredentialResolverBridge" />
<bean id="shibboleth.sp.Application" class="net.shibboleth.sp.impl.BasicApplication" abstract="true"
p:metricName="net.shibboleth.sp.relyingparty.configurations" />
@@ -92,8 +93,16 @@
<!-- More traditional beans akin to IdP service. -->
+ <bean id="shibboleth.sp.CredentialResolverBridge" class="net.shibboleth.sp.credential.impl.CredentialResolverBridge"
+ c:requestSupplier-ref="shibboleth.HttpServletRequestSupplier"
+ c:resolver-ref="shibboleth.sp.CredentialResolverService" />
+
<bean id="shibboleth.sp.DefaultSecurityConfiguration" class="org.opensaml.security.config.BasicSecurityConfiguration" />
+ <bean id="shibboleth.sp.BasicHttpClientSecurityConfiguration"
+ class="net.shibboleth.sp.security.config.impl.BasicHttpClientSecurityConfiguration"
+ c:resolver-ref="shibboleth.sp.CredentialResolverBridge" />
+
<!-- We set the honor-empty flag on this so that the typical case of an empty profile map is assumed to be valid. -->
<bean id="DefaultUnverifiedRelyingPartyConfiguration" class="net.shibboleth.sp.impl.DelegatingRelyingPartyConfiguration"
p:honorEmptyProfileCollection="true"
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/credentials-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/credentials-system.xml
new file mode 100644
index 0000000..84dcac3
--- /dev/null
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/credentials-system.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- Needed to allow for auto-wiring of components. -->
+ <context:annotation-config />
+
+ <!-- Exposes configured resolvers as a callable service. -->
+ <bean class="org.opensaml.security.credential.impl.ChainingCredentialResolver" />
+
+ <!-- Wildcard import hook for plugins. -->
+ <import resource="classpath*:/META-INF/net/shibboleth/sp/service/credentials/postconfig.xml" />
+
+</beans>
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/module.properties b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/module.properties
index 07f750e..517ae43 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/module.properties
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/module.properties
@@ -13,8 +13,11 @@ sp.Core.url = https://shibboleth.atlassian.net/wiki/spaces/sphub1
sp.Core.1.src = /net/shibboleth/idp/module/conf/sp/agents.xml
sp.Core.1.dest = conf/sp/agents.xml
-sp.Core.2.src = /net/shibboleth/idp/module/conf/sp/sp.properties
-sp.Core.2.dest = conf/sp/sp.properties
+sp.Core.2.src = /net/shibboleth/idp/module/conf/sp/credentials.xml
+sp.Core.2.dest = conf/sp/credentials.xml
-sp.Core.3.src = /net/shibboleth/idp/module/conf/examples/attribute-filter-sp.xml
-sp.Core.3.dest = conf/examples/attribute-filter-sp.xml
+sp.Core.3.src = /net/shibboleth/idp/module/conf/sp/sp.properties
+sp.Core.3.dest = conf/sp/sp.properties
+
+sp.Core.4.src = /net/shibboleth/idp/module/conf/examples/attribute-filter-sp.xml
+sp.Core.4.dest = conf/examples/attribute-filter-sp.xml
diff --git a/sp-conf-impl/src/test/resources/net/shibboleth/sp/service/utility.xml b/sp-conf-impl/src/test/resources/net/shibboleth/sp/service/utility.xml
index cecbf8f..fa58cf6 100644
--- a/sp-conf-impl/src/test/resources/net/shibboleth/sp/service/utility.xml
+++ b/sp-conf-impl/src/test/resources/net/shibboleth/sp/service/utility.xml
@@ -27,12 +27,16 @@
<bean id="shibboleth.AttributeResolverService" class="net.shibboleth.shared.testing.MockReloadableService" />
<bean id="shibboleth.AttributeFilterService" class="net.shibboleth.shared.testing.MockReloadableService" />
<bean id="shibboleth.AttributeRegistryService" class="net.shibboleth.shared.testing.MockReloadableService" />
+ <bean id="shibboleth.sp.CredentialResolverService" class="net.shibboleth.shared.testing.MockReloadableService" />
<!-- Used for mocking AgentResolver's state manager beans. -->
<bean id="shibboleth.StorageService"
class="org.opensaml.storage.impl.MemoryStorageService" />
+ <bean id="shibboleth.HttpServletRequestSupplier"
+ class="net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletRequestSupplier" />
+
<bean id="shibboleth.RemotedHttpServletRequestSupplier"
class="net.shibboleth.sp.messaging.impl.RemotedHttpServletRequestSupplier" />
<bean id="shibboleth.RemotedHttpServletResponseSupplier"
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/credential/AbstractOrderedCredentialResolver.java b/sp-server-api/src/main/java/net/shibboleth/sp/credential/AbstractOrderedCredentialResolver.java
index bffe302..96cf8c4 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/credential/AbstractOrderedCredentialResolver.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/credential/AbstractOrderedCredentialResolver.java
@@ -59,6 +59,13 @@ public abstract class AbstractOrderedCredentialResolver extends AbstractIdentifi
/** Protocol values supported by these credentials. */
private Set<String> supportedProtocols;
+
+ /** Constructor. */
+ public AbstractOrderedCredentialResolver() {
+ order = Ordered.LOWEST_PRECEDENCE;
+ filterByUsage = true;
+ supportedProtocols = CollectionSupport.emptySet();
+ }
/** {@inheritDoc} */
public int getOrder() {
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/credential/package-info.java b/sp-server-api/src/main/java/net/shibboleth/sp/credential/package-info.java
new file mode 100644
index 0000000..5fac2e3
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/credential/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/**
+ * APIs for resolving and exposing credentials.
+ */
+package net.shibboleth.sp.credential;
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/package-info.java b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/package-info.java
new file mode 100644
index 0000000..48b037f
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation classes for SP credential resolution and access.
+ */
+package net.shibboleth.sp.credential.impl;
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
index 7b4abe2..8ffa7d2 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
@@ -29,6 +29,10 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.security.config.SecurityConfiguration;
import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialResolver;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.criteria.UsageCriterion;
+import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -51,6 +55,7 @@ import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
import net.shibboleth.shared.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.ResolverException;
@@ -66,6 +71,9 @@ import net.shibboleth.spring.security.CredentialHolder;
*/
public class BasicApplication extends BasicRelyingPartyConfiguration implements Application {
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BasicApplication.class);
+
/** Link to parent {@link Application}. */
@Nullable private Application parent;
@@ -117,6 +125,9 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
/** Attribute filter. */
@Nullable private ReloadableService<AttributeFilter> attributeFilter;
+ /** Access to credentials indirectly. */
+ @Nullable private CredentialResolver credentialResolver;
+
/**
* Constructor.
*
@@ -593,6 +604,24 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
}
}
+ /**
+ * Sets a {@link CredentialResolver} to use for resolving keys and certificates "indirectly"
+ * in support of the deprecated older methods.
+ *
+ * <o>This method should not be relied on "publically", and is solely used internally for
+ * backward compatibility.</p>
+ *
+ * @param resolver
+ *
+ * @deprecated
+ */
+ @Deprecated(since="1.0.0", forRemoval=true)
+ public void setCredentialResolver(@Nullable final CredentialResolver resolver) {
+ checkSetterPreconditions();
+
+ credentialResolver = resolver;
+ }
+
// Override RelyingPartyConfiguration getters for inheritance purposes.
/** {@inheritDoc} */
@@ -838,6 +867,16 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
if (allowInheritance && parent instanceof BasicApplication basic) {
return basic.getSigningCredentials();
}
+
+ final CredentialResolver localResolver = credentialResolver;
+ if (localResolver != null) {
+ try {
+ final ArrayList<Credential> accumulator = new ArrayList<>();
+ localResolver.resolve(new CriteriaSet(new UsageCriterion(UsageType.SIGNING))).forEach(accumulator::add);
+ } catch (final ResolverException e) {
+ log.error("Error resolving signing credentials", e);
+ }
+ }
return CollectionSupport.emptyList();
}
@@ -853,6 +892,16 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
if (allowInheritance && parent instanceof BasicApplication basic) {
return basic.getEncryptionCredentials();
}
+
+ final CredentialResolver localResolver = credentialResolver;
+ if (localResolver != null) {
+ try {
+ final ArrayList<Credential> accumulator = new ArrayList<>();
+ localResolver.resolve(new CriteriaSet(new UsageCriterion(UsageType.ENCRYPTION))).forEach(accumulator::add);
+ } catch (final ResolverException e) {
+ log.error("Error resolving decryption credentials", e);
+ }
+ }
return CollectionSupport.emptyList();
}
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/security/config/impl/package-info.java b/sp-server-impl/src/main/java/net/shibboleth/sp/security/config/impl/package-info.java
new file mode 100644
index 0000000..45d23f8
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/security/config/impl/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/**
+ * Classes supplementing OpenSAML security configuration support.
+ */
+package net.shibboleth.sp.security.config.impl;
\ 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