This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch fix/rfc9068-at-jwt-type
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit f474343721ee59663ac6fc26f91200c82be680c0
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Mar 11 18:16:17 2026 +0100

    RFC 9068: Set typ header to at+jwt for JWT access tokens
    
    Per RFC 9068 Section 2.1, JWT access tokens MUST include a typ
    header parameter set to "at+jwt". This change:
    
    - Adds TYPE_AT_JWT constant to JoseConstants
    - Adds AT_JWT member to JoseType enum with proper lookup
    - Sets the at+jwt type on both JWS and JWE headers when producing
      JWT access tokens in AbstractOAuthDataProvider
    
    Closes #990
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../java/org/apache/cxf/rs/security/jose/common/JoseConstants.java | 1 +
 .../main/java/org/apache/cxf/rs/security/jose/common/JoseType.java | 5 ++++-
 .../cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java | 7 ++++++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git 
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseConstants.java
 
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseConstants.java
index 092581d3fd..017f814411 100644
--- 
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseConstants.java
+++ 
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseConstants.java
@@ -43,6 +43,7 @@ public final class JoseConstants extends RSSecurityConstants {
     public static final String JWS_HEADER_B64_STATUS_HEADER = "b64";
 
     public static final String TYPE_JWT = "JWT";
+    public static final String TYPE_AT_JWT = "at+jwt";
     public static final String TYPE_JOSE = "JOSE";
     public static final String TYPE_JOSE_JSON = "JOSE+JSON";
     public static final String MEDIA_TYPE_JOSE = "application/jose";
diff --git 
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseType.java
 
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseType.java
index 647fb163fe..cea5fdf0a8 100644
--- 
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseType.java
+++ 
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseType.java
@@ -22,7 +22,8 @@ package org.apache.cxf.rs.security.jose.common;
 public enum JoseType {
     JOSE(JoseConstants.TYPE_JOSE),
     JOSE_JSON(JoseConstants.TYPE_JOSE_JSON),
-    JWT(JoseConstants.TYPE_JWT);
+    JWT(JoseConstants.TYPE_JWT),
+    AT_JWT(JoseConstants.TYPE_AT_JWT);
 
     private final String type;
     JoseType(String type) {
@@ -33,6 +34,8 @@ public enum JoseType {
             return null;
         } else if (JoseConstants.TYPE_JOSE_JSON.equals(type)) {
             return JOSE_JSON;
+        } else if (JoseConstants.TYPE_AT_JWT.equals(type)) {
+            return AT_JWT;
         } else {
             return valueOf(type);
         }
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
index 26f7492849..a78f0d9df8 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import jakarta.ws.rs.core.MultivaluedMap;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.common.JoseType;
 import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
@@ -669,7 +670,11 @@ public abstract class AbstractOAuthDataProvider implements 
OAuthDataProvider, Cl
         // It will JWS-sign (default) and/or JWE-encrypt
         OAuthJoseJwtProducer processor =
             getJwtAccessTokenProducer() == null ? new OAuthJoseJwtProducer() : 
getJwtAccessTokenProducer();
-        return processor.processJwt(new JwtToken(jwtCliams));
+        JwtToken jwt = new JwtToken(jwtCliams);
+        // RFC 9068 Section 2.1: JWT access tokens MUST set typ to "at+jwt"
+        jwt.getJwsHeaders().setType(JoseType.AT_JWT);
+        jwt.getJweHeaders().setType(JoseType.AT_JWT);
+        return processor.processJwt(jwt);
     }
 
     public Map<String, String> getJwtAccessTokenClaimMap() {

Reply via email to