[java-idp-plugin-oidc-op-oidfed] 02/02: Improved error response contents
Henri Mikkonen
henri.mikkonen at iki.fi
Wed Oct 8 11:49:41 UTC 2025
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-idp-plugin-oidc-op-oidfed.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-op-oidfed.git;a=commit;h=4432a0d7051d95b17d420abdbdcd0c191c7a9b3c
commit 4432a0d7051d95b17d420abdbdcd0c191c7a9b3c
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Oct 8 14:48:54 2025 +0300
Improved error response contents
- New event ID to signal if no trust chains could be resolved "NoTrustChainsResolved"
- Event mapped to PAR and explicit registration responses
- Explicit registration exploits new map 'shibboleth.oidfed.register.DefaultMappedErrors'
- It extends the OIDC dynamic client registration's mapped errors
- May be overridden by 'shibboleth.oidfed.register.MappedErrors'
---
.../oidfed/profile/impl/OidFederationEventIds.java | 5 +++++
.../op/oidfed/profile/impl/ResolveTrustChains.java | 4 +++-
.../op/oidfed/profile/impl/SelectTrustChain.java | 1 +
.../META-INF/net.shibboleth.idp/postconfig.xml | 24 ++++++++++++++++++++++
.../oidfed/metadata-lookup-ext-oidfed-beans.xml | 7 +------
.../oidfed/metadata-lookup-ext-oidfed-flow.xml | 2 ++
.../idp/flows/oidfed/register/register-beans.xml | 13 ++++++------
.../profile/flow/oidfed/RegistrationFlowTest.java | 10 ++++-----
8 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
index 2558d9f..ec5bbbe 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
@@ -40,6 +40,11 @@ public class OidFederationEventIds {
@Nonnull @NotEmpty public static final String CACHED_ENTITY_CONFIGURATION_RESPONSE =
"CachedEntityConfigurationResponseFound";
+ /**
+ * ID of event returned if no trust chains were resolved for the client.
+ */
+ @Nonnull @NotEmpty public static final String NO_TRUST_CHAINS_RESOLVED = "NoTrustChainsResolved";
+
/**
* ID of event returned if the given trust anchor is invalid.
*/
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
index dd942fa..3607b51 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
@@ -221,10 +221,12 @@ public class ResolveTrustChains extends AbstractTrustChainResolutionAction {
cacheResult = trustChainCache.get(criteriaSet);
} catch (final MetadataCacheException e) {
log.warn("{} Could fetch trust chains for {}", getLogPrefix(), clientId);
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED);
return;
}
if (cacheResult.isEmpty()) {
log.debug("{} No trust chains resolved for {}", getLogPrefix(), clientId);
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED);
return;
}
final List<String> preSelectedChain =
@@ -249,7 +251,7 @@ public class ResolveTrustChains extends AbstractTrustChainResolutionAction {
if (policyCompliantChains.isEmpty()) {
if (errorEventId == null) {
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED);
} else {
ActionSupport.buildEvent(profileRequestContext, errorEventId);
}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
index 085ffdb..77e4e34 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
@@ -139,6 +139,7 @@ public class SelectTrustChain extends AbstractProfileAction {
trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
if (trustChainContext == null || trustChainContext.getPolicyCompliantTrustChains() == null) {
log.debug("{} Unable to locate policy-compliant trust chains, nothing to do", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED);
return false;
}
return true;
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index a94a38f..cb15816 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -386,6 +386,21 @@
</property>
</bean>
+ <bean id="shibboleth.oidfed.register.DefaultMappedErrors"
+ parent="shibboleth.oidc.register.DefaultMappedErrors"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map value-type="com.nimbusds.oauth2.sdk.ErrorObject">
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable trust chains could be resolved for the client" c:_2="401" />
+ </entry>
+ </map>
+ </property>
+ </bean>
+
<bean id="DefaultTrustMarkClaimsValidationLookupStrategy" parent="shibboleth.Functions.Constant">
<constructor-arg name="target">
<bean class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator">
@@ -564,6 +579,15 @@
</property>
</bean>
+ <bean parent="shibboleth.oidc.PushedAuthorizationErrorMapping">
+ <property name="eventId">
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.NO_TRUST_CHAINS_RESOLVED"/>
+ </property>
+ <property name="errorObject">
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable trust chains could be resolved for the client" c:_2="401" />
+ </property>
+ </bean>
+
<alias alias="UseResolverApiCondition" name="%{idp.oidfed.trustchain.resolver.useResolverApiCondition:shibboleth.Conditions.FALSE}" />
<alias alias="FallbackToLocalResolutionCondition" name="%{idp.oidfed.trustchain.resolver.fallbackToLocalCondition:shibboleth.Conditions.TRUE}" />
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml
index 4a4cacc..3c502ef 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml
@@ -101,12 +101,7 @@
p:profileId="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationAutomaticRegistrationProfileConfiguration).PROFILE_ID}" />
<bean id="SelectTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.SelectTrustChain"
- scope="prototype">
- <property name="activationCondition">
- <bean parent="shibboleth.Conditions.Expression"
- c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
- </property>
- </bean>
+ scope="prototype"/>
<bean id="ResolveTrustMarks" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustMarks"
scope="prototype"
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml
index 51d6133..bbe8d1a 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml
@@ -59,11 +59,13 @@
<end-state id="proceed"/>
<end-state id="InvalidMetadataPolicy"/>
<end-state id="InvalidMetadataAgainstPolicy"/>
+ <end-state id="NoTrustChainsResolved" />
<end-state id="HandleError"/>
<global-transitions>
<transition on="InvalidMetadataPolicy" to="InvalidMetadataPolicy" />
<transition on="InvalidMetadataAgainstPolicy" to="InvalidMetadataAgainstPolicy" />
+ <transition on="NoTrustChainsResolved" to="NoTrustChainsResolved" />
<transition on="HandleError" to="HandleError" />
</global-transitions>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
index 8b6529c..bd090cc 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
@@ -179,12 +179,7 @@
<bean id="SelectTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.SelectTrustChain"
scope="prototype"
- p:relyingPartyContextCreationStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy">
- <property name="activationCondition">
- <bean parent="shibboleth.Conditions.Expression"
- c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
- </property>
- </bean>
+ p:relyingPartyContextCreationStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy"/>
<bean id="ResolveTrustMarks" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustMarks"
scope="prototype"
@@ -201,6 +196,10 @@
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"
p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
</property>
+ <property name="activationCondition">
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+ </property>
</bean>
<bean id="RelyingPartyTrustChainContextLookupStrategy" parent="shibboleth.Functions.Expression"
@@ -305,7 +304,7 @@
class="net.shibboleth.idp.plugin.oidc.op.profile.impl.BuildRegistrationErrorResponseFromEvent"
scope="prototype"
p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier"
- p:mappedErrors="#{getObject('shibboleth.oidc.register.MappedErrors') ?: getObject('shibboleth.oidc.register.DefaultMappedErrors')}">
+ p:mappedErrors="#{getObject('shibboleth.oidfed.register.MappedErrors') ?: getObject('shibboleth.oidfed.register.DefaultMappedErrors')}">
<property name="eventContextLookupStrategy">
<bean
class="net.shibboleth.idp.profile.context.navigate.WebFlowCurrentEventLookupFunction" />
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
index 6d987a4..387b78e 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
@@ -65,14 +65,14 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
public void testInvalidContentType() throws Exception {
setJsonRequest("POST", "{}");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_client_metadata");
+ assertErrorCode(result, "invalid_request");
}
@Test
public void testEmptyEntityConfiguration() throws Exception {
setRequest("POST", "", "application/entity-statement+jwt");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_client_metadata");
+ assertErrorCode(result, "invalid_request");
}
@Test
@@ -96,7 +96,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
rpConfigureMockHttpClient(clientId);
setRequest("POST", rpEntityConfiguration(clientId), "application/json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_client_metadata");
+ assertErrorCode(result, "invalid_request");
}
@Test
@@ -131,7 +131,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
verify(federationHttpClient, times(0)).executeOpen(any(),
argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -143,7 +143,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
verify(federationHttpClient, times(0)).executeOpen(any(),
argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list