Skip to content

Commit 2c2a341

Browse files
gnodetclaude
authored andcommitted
RFC 9068: Set typ header to at+jwt for JWT access tokens (#2948)
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 <noreply@anthropic.com>
1 parent 1dbce69 commit 2c2a341

3 files changed

Lines changed: 11 additions & 2 deletions

File tree

rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public final class JoseConstants extends RSSecurityConstants {
4343
public static final String JWS_HEADER_B64_STATUS_HEADER = "b64";
4444

4545
public static final String TYPE_JWT = "JWT";
46+
public static final String TYPE_AT_JWT = "at+jwt";
4647
public static final String TYPE_JOSE = "JOSE";
4748
public static final String TYPE_JOSE_JSON = "JOSE+JSON";
4849
public static final String MEDIA_TYPE_JOSE = "application/jose";

rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
public enum JoseType {
2323
JOSE(JoseConstants.TYPE_JOSE),
2424
JOSE_JSON(JoseConstants.TYPE_JOSE_JSON),
25-
JWT(JoseConstants.TYPE_JWT);
25+
JWT(JoseConstants.TYPE_JWT),
26+
AT_JWT(JoseConstants.TYPE_AT_JWT);
2627

2728
private final String type;
2829
JoseType(String type) {
@@ -33,6 +34,8 @@ public static JoseType getType(String type) {
3334
return null;
3435
} else if (JoseConstants.TYPE_JOSE_JSON.equals(type)) {
3536
return JOSE_JSON;
37+
} else if (JoseConstants.TYPE_AT_JWT.equals(type)) {
38+
return AT_JWT;
3639
} else {
3740
return valueOf(type);
3841
}

rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import org.apache.cxf.jaxrs.ext.MessageContext;
3030
import org.apache.cxf.rs.security.jose.common.JoseConstants;
31+
import org.apache.cxf.rs.security.jose.common.JoseType;
3132
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
3233
import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
3334
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
@@ -707,7 +708,11 @@ protected String processJwtAccessToken(JwtClaims jwtCliams) {
707708
// It will JWS-sign (default) and/or JWE-encrypt
708709
OAuthJoseJwtProducer processor =
709710
getJwtAccessTokenProducer() == null ? new OAuthJoseJwtProducer() : getJwtAccessTokenProducer();
710-
return processor.processJwt(new JwtToken(jwtCliams));
711+
JwtToken jwt = new JwtToken(jwtCliams);
712+
// RFC 9068 Section 2.1: JWT access tokens MUST set typ to "at+jwt"
713+
jwt.getJwsHeaders().setType(JoseType.AT_JWT);
714+
jwt.getJweHeaders().setType(JoseType.AT_JWT);
715+
return processor.processJwt(jwt);
711716
}
712717

713718
public Map<String, String> getJwtAccessTokenClaimMap() {

0 commit comments

Comments
 (0)