From f601074e78415e41fa2ae21f8af2900f4c995823 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 7 Apr 2026 10:45:44 +0200 Subject: [PATCH] fix: include resource parameter in OIDC token exchange request Logto returns opaque access tokens unless the resource parameter is included in both the authorization request AND the token exchange. Append resource to the token endpoint POST body per RFC 8707 so Logto returns a JWT access token with Custom JWT claims. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../cameleer3/server/app/security/OidcTokenExchanger.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcTokenExchanger.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcTokenExchanger.java index af4e68a8..c70c1d2c 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcTokenExchanger.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcTokenExchanger.java @@ -80,6 +80,13 @@ public class OidcTokenExchanger { log.info("OIDC token exchange: tokenEndpoint={}, redirectUri={}", metadata.getTokenEndpointURI(), redirectUri); var httpRequest = tokenRequest.toHTTPRequest(); + // RFC 8707: include resource indicator in token exchange to get a JWT access token + String configAudience = config.audience() != null ? config.audience() : ""; + if (!configAudience.isBlank()) { + String body = httpRequest.getBody(); + body += "&resource=" + java.net.URLEncoder.encode(configAudience, java.nio.charset.StandardCharsets.UTF_8); + httpRequest.setBody(body); + } if (securityProperties.isOidcTlsSkipVerify()) { httpRequest.setSSLSocketFactory(InsecureTlsHelper.socketFactory()); httpRequest.setHostnameVerifier(InsecureTlsHelper.hostnameVerifier());