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));

Reply via email to