This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch coheigea/OidcClientCodeRequestFilter in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 92d624d20857c66b94677a578035ac60a19b1833 Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Fri Aug 7 12:35:09 2026 +0100 Fix max_age check in OidcClientCodeRequestFilter --- .../rs/security/oidc/rp/OidcClientCodeRequestFilter.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java index 1d9fa450ef5..d745dc2c4e9 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java @@ -135,7 +135,9 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { protected MultivaluedMap<String, String> toCodeRequestState(ContainerRequestContext rc, UriInfo ui) { MultivaluedMap<String, String> state = super.toCodeRequestState(rc, ui); if (maxAgeOffset != null) { - state.putSingle(MAX_AGE_PARAMETER, Long.toString(System.currentTimeMillis() + maxAgeOffset)); + // Store the earliest acceptable auth_time (seconds) so validateIdToken can compare + // directly against the id_token auth_time claim, which is also in seconds. + state.putSingle(MAX_AGE_PARAMETER, Long.toString(System.currentTimeMillis() / 1000 - maxAgeOffset)); } // Per OIDC Core §3.2.2.1 and §3.3.2.1, a nonce is REQUIRED for Implicit and Hybrid flows // (any response_type containing "id_token"). Auto-generate one if the caller has not @@ -165,9 +167,10 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST); } if (maxAgeOffset != null) { - long authTime = Long.parseLong(state.getFirst(MAX_AGE_PARAMETER)); + long minAuthTime = Long.parseLong(state.getFirst(MAX_AGE_PARAMETER)); Long tokenAuthTime = idToken.getAuthenticationTime(); - if (tokenAuthTime > authTime) { + // auth_time is required when max_age was requested (OIDC Core §3.1.3.7). + if (tokenAuthTime == null || tokenAuthTime < minAuthTime) { throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST); } } @@ -209,8 +212,9 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { if (nonce != null) { ub.queryParam(IdToken.NONCE_CLAIM, nonce); } - if (redirectState != null && redirectState.getFirst(MAX_AGE_PARAMETER) != null) { - ub.queryParam(MAX_AGE_PARAMETER, redirectState.getFirst(MAX_AGE_PARAMETER)); + if (maxAgeOffset != null) { + // max_age is a duration in seconds per OIDC Core §3.1.2.1, not a timestamp. + ub.queryParam(MAX_AGE_PARAMETER, Long.toString(maxAgeOffset)); } if (codeRequestState != null && codeRequestState.getFirst(LOGIN_HINT_PARAMETER) != null) { ub.queryParam(LOGIN_HINT_PARAMETER, codeRequestState.getFirst(LOGIN_HINT_PARAMETER));
