[java-idp-oidc] 01/02: JOIDC-222 - Support for OpenID Federation
Henri Mikkonen
henri.mikkonen at iki.fi
Tue Apr 22 07:26:28 UTC 2025
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch dev/JOIDC-222
in repository java-idp-oidc.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=2c23bee08035b44f9d310b71bc5095464a7ad30d
commit 2c23bee08035b44f9d310b71bc5095464a7ad30d
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Tue Apr 22 10:24:51 2025 +0300
JOIDC-222 - Support for OpenID Federation
https://shibboleth.atlassian.net/browse/JOIDC-222
Adapted into the new trust mark ID naming
- Use 'trust_mark_id' instead of 'id' claim
- Parse trust marks directly from the JWT claims set (not via EntityStatement)
- Store validated trust marks into RelyingPartyTrustChainContext (in addition to identifiers)
---
...DefaultTrustChainTrustMarksParsingStrategy.java | 39 ++++++++++++----------
.../impl/RelyingPartyTrustChainContext.java | 26 +++++++++++++++
.../op/oidfed/profile/impl/ResolveTrustMarks.java | 15 ++++++---
3 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java
index f0add6d7..5ee66542 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java
@@ -18,6 +18,7 @@ import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -28,7 +29,6 @@ import org.slf4j.Logger;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.id.Identifier;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -62,11 +62,14 @@ public class DefaultTrustChainTrustMarksParsingStrategy
log.trace("Inspecting entity statement {} with trust marks {}",
statementJwt.serialize(), statement.getClaimsSet().getTrustMarks());
- if (statement.getClaimsSet().getTrustMarks() != null) {
- final List<SignedJWT> trustMarks = statement.getClaimsSet().getTrustMarks()
+ final List<Object> rawTrustMarks = statement.getClaimsSet().getJSONArrayClaim("trust_marks");
+ if (rawTrustMarks != null && !rawTrustMarks.isEmpty()) {
+ final List<SignedJWT> trustMarks = rawTrustMarks
.stream()
- .filter(entry -> verifyTrustMark(entry.getTrustMark(), entry.getID()))
- .map(entry -> entry.getTrustMark())
+ .filter(Map.class::isInstance)
+ .map(Map.class::cast)
+ .map(map -> parseTrustMark(map.get("trust_mark"), map.get("trust_mark_id")))
+ .filter(Objects::nonNull)
.toList();
result.put(statement.getEntityID().getValue(), trustMarks);
}
@@ -78,27 +81,29 @@ public class DefaultTrustChainTrustMarksParsingStrategy
/**
* Verifies the trust mark id and issuer claims.
*
- * @param trustMark trust mark to be verified
+ * @param trustMark trust mark to be verified, expected to be parseable from string
* @param id the id to be verified from the JWT claims set
- * @return true if valid, false otherwise
+ * @return trust mark JWT if valid, null otherwise
*/
- private boolean verifyTrustMark(@Nullable final SignedJWT trustMark, @Nullable final Identifier id) {
- if (trustMark == null || id == null) {
- return false;
+ @Nullable private SignedJWT parseTrustMark(@Nullable final Object trustMark, @Nullable final Object id) {
+ if (trustMark == null || !(trustMark instanceof String) || id == null || !(id instanceof String)) {
+ return null;
}
try {
- final JWTClaimsSet trustMarkClaims = trustMark.getJWTClaimsSet();
+ final SignedJWT jwt = SignedJWT.parse((String) trustMark);
+ final JWTClaimsSet trustMarkClaims = jwt.getJWTClaimsSet();
if (StringSupport.trimOrNull(trustMarkClaims.getIssuer()) == null) {
- log.error("Trust Mark {} is missing mandatory issuer", trustMarkClaims.getStringClaim("id"));
- return false;
+ log.error("Trust Mark {} is missing mandatory issuer", trustMarkClaims.getStringClaim("trust_mark_id"));
+ return null;
}
- if (id.getValue().equals(trustMarkClaims.getStringClaim("id"))) {
- return true;
+ if (id.equals(trustMarkClaims.getStringClaim("trust_mark_id"))) {
+ return jwt;
}
- log.error("The id {} is not matching with the id-claim {}", id, trustMarkClaims.getStringClaim("id"));
+ log.error("The id {} is not matching with the trust_mark_id-claim {}", id,
+ trustMarkClaims.getStringClaim("trust_mark_id"));
} catch (final ParseException e) {
log.error("Could not parse id-claim from the trust mark", e);
}
- return false;
+ return null;
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java
index 37f0a031..8a6ff150 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java
@@ -23,6 +23,7 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.context.BaseContext;
+import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
@@ -50,6 +51,9 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
/** Verified trust mark IDs for the selected trust chain. */
@Nullable private Map<String, List<String>> verifiedTrustMarkIds;
+ /** Verified trust marks for the selected trust chain. */
+ @Nullable private Map<String, List<SignedJWT>> verifiedTrustMarks;
+
/** All previously selected but rejected trust chains. */
@Nullable private List<List<EntityStatement>> rejectedTrustChains;
@@ -162,6 +166,28 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
return this;
}
+ /**
+ * Get the verified trust marks for the selected trust chain.
+ *
+ * @return verified trust marks
+ */
+ @Nullable public Map<String, List<SignedJWT>> getVerifiedTrustMarks() {
+ return verifiedTrustMarks;
+ }
+
+ /**
+ * Set the verified trust marks for the selected trust chain.
+ *
+ * @param trustmarks verified trust marks
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarks(
+ @Nullable final Map<String, List<SignedJWT>> trustMarks) {
+ verifiedTrustMarks = trustMarks;
+ return this;
+ }
+
/**
* Get the previously selected but rejected trust chains for the relying party.
*
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
index ac8b9712..34d729fb 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
@@ -22,6 +22,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -243,7 +244,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
return;
}
- final Map<String, List<String>> verifiedTrustMarks = new HashMap<>();
+ final Map<String, List<SignedJWT>> verifiedTrustMarks = new HashMap<>();
for (final EntityStatement statement : selectedTrustChain) {
final List<SignedJWT> trustMarks = chainTrustMarks.get(statement.getEntityID().getValue());
if (trustMarks == null || trustMarks.isEmpty()) {
@@ -254,12 +255,16 @@ public class ResolveTrustMarks extends AbstractProfileAction {
trustMarks.stream()
.filter(entry -> checkTrustedIssuer(entry))
.filter(entry -> verifyTrustMark(entry))
- .map(entry -> getTrustMarkId(entry))
.filter(Objects::nonNull)
.toList());
}
- log.debug("{} The following trust marks are validated: {}", getLogPrefix(), verifiedTrustMarks);
- trustChainContext.setVerifiedTrustMarkIds(verifiedTrustMarks);
+ trustChainContext.setVerifiedTrustMarks(verifiedTrustMarks);
+ final Map<String, List<String>> verifiedTrustMarkIds = verifiedTrustMarks.entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().stream()
+ .map(list -> getTrustMarkId(list))
+ .toList()));
+ log.debug("{} The following trust marks are validated: {}", getLogPrefix(), verifiedTrustMarkIds);
+ trustChainContext.setVerifiedTrustMarkIds(verifiedTrustMarkIds);
}
/**
@@ -351,7 +356,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
*/
@Nullable private String getTrustMarkId(@Nullable final SignedJWT trustMark) {
try {
- return trustMark == null ? null : trustMark.getJWTClaimsSet().getStringClaim("id");
+ return trustMark == null ? null : trustMark.getJWTClaimsSet().getStringClaim("trust_mark_id");
} catch (final ParseException e) {
log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list