[java-idp-plugin-oidc-op-oidfed] 01/02: Fixed the wiring of authority_hints: it should only be included in the entity configuration
Codeberg
noreply at shibboleth.net
Fri Nov 28 07:24:31 UTC 2025
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-idp-plugin-oidc-op-oidfed.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-oidc-op-oidfed/commit/3a5ef4b4b1c3c2016052f12d8c5d3feea1751b4e
commit 3a5ef4b4b1c3c2016052f12d8c5d3feea1751b4e
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Nov 28 07:58:16 2025 +0200
Fixed the wiring of authority_hints: it should only be included in the entity configuration
- Explicit registration response uses it for the immediate superior
- Improved tests
---
.../impl/AbstractBuildEntityStatementAction.java | 10 +------
.../profile/impl/BuildEntityConfiguration.java | 35 +++++++++++++++++++++-
.../flow/oidfed/EntityConfigurationFlowTest.java | 3 ++
.../profile/flow/oidfed/RegistrationFlowTest.java | 2 ++
.../profile/flow/oidfed/ResolveEntityFlowTest.java | 2 ++
.../net/shibboleth/idp/module/conf/idp.properties | 3 +-
.../idp/module/conf/oidfed/oidfed.properties | 1 +
7 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java
index 761baf9..e77eb2a 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java
@@ -17,7 +17,6 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
import java.text.ParseException;
import java.time.Instant;
import java.util.Date;
-import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -40,7 +39,6 @@ import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
-import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.AuthorityHintsLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.EntityStatementClaimsSetManipulationStrategyLookupFunction;
import net.shibboleth.idp.profile.AbstractProfileAction;
import net.shibboleth.idp.profile.IdPEventIds;
@@ -78,9 +76,6 @@ public abstract class AbstractBuildEntityStatementAction extends AbstractProfile
/** Strategy used to locate the subcontext to hold the statement. */
@Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
- /** Strategy used to locate authority hints. */
- @Nonnull private Function<ProfileRequestContext,List<String>> authorityHintsLookupStrategy;
-
/** Lookup function to supply strategy bi-function for manipulating entity statement claims set. */
@Nonnull
private Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
@@ -111,8 +106,6 @@ public abstract class AbstractBuildEntityStatementAction extends AbstractProfile
assert escls != null;
entityStatementContextLookupStrategy = escls;
- authorityHintsLookupStrategy = new AuthorityHintsLookupFunction();
-
entityStatementClaimsSetManipulationStrategyLookupStrategy =
new EntityStatementClaimsSetManipulationStrategyLookupFunction();
}
@@ -238,8 +231,7 @@ public abstract class AbstractBuildEntityStatementAction extends AbstractProfile
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
.issuer(issuer)
.subject(subject)
- .issueTime(Date.from(now))
- .claim("authority_hints", authorityHintsLookupStrategy.apply(profileRequestContext));
+ .issueTime(Date.from(now));
assert builder != null;
if (!populateClaimsSetBuilder(builder, profileRequestContext)) {
return;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
index 7ac31f7..2e1d935 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
@@ -33,6 +33,7 @@ import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jwt.JWTClaimsSet;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.AuthorityHintsLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.EntityStatementLifetimeLookupFunction;
import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction;
@@ -65,6 +66,9 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
/** Strategy used to obtain the entity statement lifetime. */
@Nonnull private Function<ProfileRequestContext,Duration> entityConfigurationLifetimeLookupStrategy;
+ /** Strategy used to locate authority hints. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> authorityHintsLookupStrategy;
+
/** Metadata to publish. */
@NonnullBeforeExec private Map<String,Map<String,Object>> metadata;
@@ -72,6 +76,20 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
public BuildEntityConfiguration() {
signingConfigurationsLookupStrategy = new JWTSignatureSigningConfigurationLookupFunction();
entityConfigurationLifetimeLookupStrategy = new EntityStatementLifetimeLookupFunction();
+ authorityHintsLookupStrategy = new AuthorityHintsLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the {@link SignatureSigningConfiguration}s to fetch JWK set from.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSigningConfigurationsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,List<SignatureSigningConfiguration>> strategy) {
+ checkSetterPreconditions();
+
+ signingConfigurationsLookupStrategy =
+ Constraint.isNotNull(strategy, "Signing configuration lookup strategy cannot be null");
}
/**
@@ -81,12 +99,23 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
*/
public void setEntityConfigurationLifetimeLookupStrategy(
@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
- ifInitializedThrowUnmodifiabledComponentException();
+ checkSetterPreconditions();
entityConfigurationLifetimeLookupStrategy =
Constraint.isNotNull(strategy, "Entity configuration lifetime lookup strategy cannot be null");
}
+ /**
+ * Set the strategy used to locate authority hints.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAuthorityHintsLookupStrategy(@Nonnull final Function<ProfileRequestContext,List<String>> strategy) {
+ checkSetterPreconditions();
+
+ authorityHintsLookupStrategy = Constraint.isNotNull(strategy, "Authority hints lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -140,6 +169,10 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
builder.expirationTime(Date.from(dateExp));
builder.claim("jwks", new JWKSet(jwks).toJSONObject(true));
builder.claim("metadata", CollectionSupport.copyToMap(metadata));
+ final List<String> authorityHints = authorityHintsLookupStrategy.apply(profileRequestContext);
+ if (authorityHints != null && !authorityHints.isEmpty()) {
+ builder.claim("authority_hints", authorityHints);
+ }
return true;
}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
index f079c81..0d718bc 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
@@ -30,6 +30,7 @@ import com.nimbusds.jose.Algorithm;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Response;
import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityID;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
import com.nimbusds.openid.connect.sdk.federation.entities.FederationEntityMetadata;
import com.nimbusds.openid.connect.sdk.federation.registration.ClientRegistrationType;
@@ -103,6 +104,8 @@ public class EntityConfigurationFlowTest extends AbstractFederationFlowTest {
final FederationEntityMetadata entityMetadata = entityStatement.getClaimsSet().getFederationEntityMetadata();
Assert.assertEquals(entityMetadata.getOrganizationName(), "Example organization");
Assert.assertEquals(entityMetadata.getContacts(), List.of("contact at example.org"));
+ Assert.assertEquals(entityStatement.getClaimsSet().getAuthorityHints(),
+ List.of(new EntityID("https://anchor1.example.org"), new EntityID("https://anchor2.example.org")));
}
protected boolean containsAll(Collection<? extends Algorithm> algs, Collection<String> strings) {
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 711c1e0..6200d8a 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
@@ -42,6 +42,7 @@ import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Scope;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityID;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatementClaimsSet;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
@@ -483,6 +484,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
Assert.assertEquals(storedInfo.getOIDCMetadata().getRedirectionURIStrings(),
metadata.getRedirectionURIStrings());
Assert.assertTrue(metadata.getRedirectionURIStrings().contains(redirectUri));
+ Assert.assertEquals(entityStatement.getClaimsSet().getAuthorityHints(), List.of(new EntityID(anchorId)));
return storedInfo;
}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
index c2049c0..05f1322 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
@@ -79,6 +79,7 @@ public class ResolveEntityFlowTest extends AbstractFederationFlowTest {
Assert.assertEquals(response.getHeader().getType(), new JOSEObjectType("resolve-response+jwt"));
Assert.assertEquals(response.getJWTClaimsSet().getSubject(), clientId);
Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
+ Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
}
@Test
@@ -115,6 +116,7 @@ public class ResolveEntityFlowTest extends AbstractFederationFlowTest {
Assert.assertEquals(response.getHeader().getType(), new JOSEObjectType("resolve-response+jwt"));
Assert.assertEquals(response.getJWTClaimsSet().getSubject(), entityId);
Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
+ Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
}
@Test
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties
index d78cd53..07392d5 100644
--- a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties
@@ -10,7 +10,8 @@ idp.additionalProperties = /conf/ldap.properties, \
/conf/authn/authn.properties, \
/conf/authn/duo.properties, \
/conf/oidc.properties, \
- /credentials/secrets.properties
+ /credentials/secrets.properties, \
+ /conf/oidfed/oidfed.properties
# In most cases (and unless noted in the surrounding comments) the
# commented settings in the distributed files are the default
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed.properties b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed.properties
new file mode 100644
index 0000000..a844603
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed.properties
@@ -0,0 +1 @@
+idp.oidfed.entity.authorityHints = https://anchor1.example.org, https://anchor2.example.org
\ 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