[java-idp-oidc] branch maint-4.3 updated: JOIDC-286 - Improve logging for expired sealed tokens
Codeberg
noreply at shibboleth.net
Thu Sep 10 06:52:44 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch maint-4.3
in repository java-idp-oidc.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-oidc/commit/c2c3814f4860fbaddf0647c0bb21f4645d1b1dd9
The following commit(s) were added to refs/heads/maint-4.3 by this push:
new c2c3814f JOIDC-286 - Improve logging for expired sealed tokens
c2c3814f is described below
commit c2c3814f4860fbaddf0647c0bb21f4645d1b1dd9
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Sep 10 09:34:58 2026 +0300
JOIDC-286 - Improve logging for expired sealed tokens
https://shibboleth.atlassian.net/browse/JOIDC-286
Catch DataExpiredException before DataSealerException and log it appropriately
Imported the change manually from UnwrapGrant (main branch) into ValidateGrant (maint-4.3), as JOIDC-255 had modified the structure.
---
.../oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java | 9 ++++++++-
.../idp/plugin/oidc/op/profile/impl/ValidateGrant.java | 5 +++++
.../oidc/op/profile/impl/ValidateRegistrationAccessToken.java | 5 +++++
.../logic/DefaultJwtRefreshTokenDeserializationFunction.java | 3 +++
...aultPushedAuthorizationRequestUriDeserializationFunction.java | 3 +++
.../security/jwt/claims/impl/DPoPProofNonceClaimsValidator.java | 4 ++++
.../plugin/oidc/op/userinfo/profile/impl/ParseAccessToken.java | 5 +++++
7 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
index 36d7a890..e71624e3 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
@@ -59,6 +59,7 @@ import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.ResolverException;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -268,6 +269,8 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
return null;
}
}
+ } catch (final DataExpiredException e) {
+ log.warn("{} Sealed data within the JWT access token has expired", getLogPrefix(), e);
} catch (final DataSealerException | ParseException e) {
}
@@ -278,6 +281,8 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
assert tokenValue != null;
assert dataSealer != null;
return AccessTokenClaimsSet.parse(tokenValue, dataSealer).getClaimsSet();
+ } catch (final DataExpiredException e) {
+ log.info("{} Opaque access token has expired", getLogPrefix(), e);
} catch (final DataSealerException | ParseException e) {
}
@@ -300,7 +305,9 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
assert refreshToken != null;
assert dataSealer != null;
return RefreshTokenClaimsSet.parse(refreshToken, dataSealer).getClaimsSet();
- } catch (ParseException | DataSealerException e) {
+ } catch (final DataExpiredException e) {
+ log.info("{} Opaque refresh token has expired", getLogPrefix(), e);
+ } catch (final ParseException | DataSealerException e) {
}
for (final BiFunction<ProfileRequestContext, String, RefreshTokenClaimsSet> deserializer :
refreshTokenDeserializers) {
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
index c884911d..e0d8da36 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrant.java
@@ -63,6 +63,7 @@ import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -326,6 +327,10 @@ public class ValidateGrant extends AbstractOIDCTokenResponseAction {
}
}
tokenClaimsSet = authzCodeClaimsSet;
+ } catch (final DataExpiredException e) {
+ log.info("{} Incoming authorization code has expired", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT);
+ return;
} catch (final DataSealerException | ParseException e) {
log.warn("{} Unwrapping authz code failed: {}", getLogPrefix(), e.getMessage());
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateRegistrationAccessToken.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateRegistrationAccessToken.java
index 2b16ecb1..b791775e 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateRegistrationAccessToken.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateRegistrationAccessToken.java
@@ -42,6 +42,7 @@ import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -198,6 +199,10 @@ public class ValidateRegistrationAccessToken extends AbstractOIDCRequestAction<O
final String unwrapped = dataSealer.unwrap(accessToken);
log.debug("{} Access token unwrapped into {}", getLogPrefix(), unwrapped);
claimsSet = objectMapper.readValue(unwrapped, RegistrationClaimsSet.class);
+ } catch (final DataExpiredException e) {
+ log.warn("{} Decoding access token failed: token has expired", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT);
+ return;
} catch (final DataSealerException | JsonProcessingException e) {
log.error("{} Decoding access token failed: {}", getLogPrefix(), e);
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenDeserializationFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenDeserializationFunction.java
index 38761b0b..a77e34cd 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenDeserializationFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenDeserializationFunction.java
@@ -47,6 +47,7 @@ import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.ResolverException;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -212,6 +213,8 @@ public class DefaultJwtRefreshTokenDeserializationFunction extends AbstractIniti
}
assert dataSealer != null;
return RefreshTokenClaimsSet.parse(sealedClaimsSet, dataSealer);
+ } catch (final DataExpiredException e) {
+ log.warn("Could not decrypt the sealed claims set: the data has expired", e);
} catch (final ParseException | DataSealerException e) {
log.warn("Could not decrypt the sealed claims set", e);
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultPushedAuthorizationRequestUriDeserializationFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultPushedAuthorizationRequestUriDeserializationFunction.java
index 89de84ac..b4976808 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultPushedAuthorizationRequestUriDeserializationFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultPushedAuthorizationRequestUriDeserializationFunction.java
@@ -37,6 +37,7 @@ import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -154,6 +155,8 @@ public class DefaultPushedAuthorizationRequestUriDeserializationFunction
return null;
}
return result;
+ } catch (final DataExpiredException e) {
+ log.info("The contents of the requst_uri has expired: {}", uri.toString(), e);
} catch (final DataSealerException e) {
log.debug("Could not decrypt the contents of the request_uri {}", uri.toString(), e);
return null;
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/jwt/claims/impl/DPoPProofNonceClaimsValidator.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/jwt/claims/impl/DPoPProofNonceClaimsValidator.java
index 85fb559b..d900da38 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/jwt/claims/impl/DPoPProofNonceClaimsValidator.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/jwt/claims/impl/DPoPProofNonceClaimsValidator.java
@@ -40,6 +40,7 @@ import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -160,6 +161,9 @@ public class DPoPProofNonceClaimsValidator extends AbstractClaimsValidator {
log.warn("Relying party IDs don't match: resolved '{}', nonce contained '{}'", rpId, rpIdClaim);
throw new DPoPProofNonceJWTValidationException("Relying party IDs don't match");
}
+ } catch (final DataExpiredException e) {
+ log.debug("Could not unwrap the nonce data: data has expired");
+ throw new DPoPProofNonceJWTValidationException("Could not unwrap the nonce data: data has expired");
} catch (final DataSealerException e) {
log.trace("Could not unwrap the nonce data", e);
throw new DPoPProofNonceJWTValidationException("Could not unwrap the nonce data");
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/userinfo/profile/impl/ParseAccessToken.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/userinfo/profile/impl/ParseAccessToken.java
index 19376af8..51680f51 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/userinfo/profile/impl/ParseAccessToken.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/userinfo/profile/impl/ParseAccessToken.java
@@ -46,6 +46,7 @@ import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.ResolverException;
+import net.shibboleth.shared.security.DataExpiredException;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -215,6 +216,8 @@ public class ParseAccessToken extends AbstractOIDCUserInfoValidationResponseActi
assert signedJWT != null;
assert dataSealer != null;
return AccessTokenClaimsSet.parse(signedJWT, dataSealer);
+ } catch (final DataExpiredException e) {
+ log.warn("{} Sealed data within the JWT access token has expired", getLogPrefix(), e);
} catch (final DataSealerException | ParseException e) {
}
@@ -223,6 +226,8 @@ public class ParseAccessToken extends AbstractOIDCUserInfoValidationResponseActi
try {
assert dataSealer != null;
return AccessTokenClaimsSet.parse(tokenValue, dataSealer);
+ } catch (final DataExpiredException e) {
+ log.info("{} Opaque access token has expired", getLogPrefix(), e);
} catch (final DataSealerException | ParseException e) {
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list