You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2026/09/03 15:53:44 UTC
(knox) branch master updated: KNOX-3433: set issued_token_type in KnoxIDF token responses (RFC 8693 §2.2.1) (#1375)
This is an automated email from the ASF dual-hosted git repository.
smolnar82 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 6f9460095 KNOX-3433: set issued_token_type in KnoxIDF token responses (RFC 8693 §2.2.1) (#1375)
6f9460095 is described below
commit 6f94600951397379670ab5aa30d15a5f2f51a6c2
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Thu Sep 3 17:53:38 2026 +0200
KNOX-3433: set issued_token_type in KnoxIDF token responses (RFC 8693 §2.2.1) (#1375)
---
.github/workflows/tests/test_knoxidf.py | 3 +++
.../org/apache/knox/gateway/service/knoxidf/TokenResource.java | 7 +++++++
.../org/apache/knox/gateway/util/knoxidf/KnoxIDFConstants.java | 4 ++++
3 files changed, 14 insertions(+)
diff --git a/.github/workflows/tests/test_knoxidf.py b/.github/workflows/tests/test_knoxidf.py
index b67fd0c52..70c18e08e 100644
--- a/.github/workflows/tests/test_knoxidf.py
+++ b/.github/workflows/tests/test_knoxidf.py
@@ -99,6 +99,7 @@ class TestKnoxIDF(unittest.TestCase):
tokens = response.json()
self.assertIn("access_token", tokens)
self.assertEqual(tokens["token_type"], "Bearer")
+ self.assertEqual(tokens["issued_token_type"], "urn:ietf:params:oauth:token-type:jwt")
def test_authorization_code_flow(self):
"""
@@ -136,6 +137,7 @@ class TestKnoxIDF(unittest.TestCase):
self.assertIn("access_token", tokens)
self.assertIn("id_token", tokens)
self.assertIn("refresh_token", tokens)
+ self.assertEqual(tokens["issued_token_type"], "urn:ietf:params:oauth:token-type:jwt")
refresh_token = tokens["refresh_token"]
print(f"Refresh token: {refresh_token}")
@@ -154,6 +156,7 @@ class TestKnoxIDF(unittest.TestCase):
new_tokens = response.json()
self.assertIn("access_token", new_tokens)
self.assertIn("refresh_token", new_tokens)
+ self.assertEqual(new_tokens["issued_token_type"], "urn:ietf:params:oauth:token-type:jwt")
# Verify rotation: new refresh token should be different
self.assertNotEqual(refresh_token, new_tokens["refresh_token"])
diff --git a/gateway-service-knoxidf/src/main/java/org/apache/knox/gateway/service/knoxidf/TokenResource.java b/gateway-service-knoxidf/src/main/java/org/apache/knox/gateway/service/knoxidf/TokenResource.java
index 01e5517ef..e5a198995 100644
--- a/gateway-service-knoxidf/src/main/java/org/apache/knox/gateway/service/knoxidf/TokenResource.java
+++ b/gateway-service-knoxidf/src/main/java/org/apache/knox/gateway/service/knoxidf/TokenResource.java
@@ -71,6 +71,8 @@ import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.CODE_CHALLEN
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.CODE_CHALLENGE_METHOD;
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.CODE_VERIFIER;
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.FEDERATED_IDENTITY_ID;
+import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.ISSUED_TOKEN_TYPE;
+import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.ISSUED_TOKEN_TYPE_JWT_VALUE;
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.OFFLINE_ACCESS_SCOPE;
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.PKCE_METHOD_S256;
import static org.apache.knox.gateway.util.knoxidf.KnoxIDFConstants.REDIRECT_URI;
@@ -211,6 +213,11 @@ public class TokenResource extends PasscodeTokenResourceBase {
protected ResponseMap buildResponseMap(JWT token, long expires) throws TokenServiceException {
final ResponseMap responseMap = super.buildResponseMap(token, expires);
+ // RFC 8693 §2.2.1 requires the response to state the type of the issued token. Every KnoxIDF
+ // grant (authorization_code, refresh_token and the client_credentials/other grants routed to
+ // super.doPost()) funnels through here and mints a JWT, so advertise the JWT URN unconditionally.
+ responseMap.map.put(ISSUED_TOKEN_TYPE, ISSUED_TOKEN_TYPE_JWT_VALUE);
+
// id_token + refresh-token rotation apply to the user-centric grants (authorization_code and
// refresh_token). client_credentials and other grants routed to super.doPost() must not get an
// id_token (no end user) and never carry offline_access, so they are excluded here.
diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/knoxidf/KnoxIDFConstants.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/knoxidf/KnoxIDFConstants.java
index 8c8cf6581..102297a34 100644
--- a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/knoxidf/KnoxIDFConstants.java
+++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/knoxidf/KnoxIDFConstants.java
@@ -44,6 +44,10 @@ public interface KnoxIDFConstants {
String STATE = "state";
String CODE = "code";
String REFRESH_TOKEN = "refresh_token";
+ // RFC 8693 §2.2.1: the token endpoint response must advertise the type of the issued token.
+ String ISSUED_TOKEN_TYPE = "issued_token_type";
+ //KnoxIDF always mints a JWT so issued_token_type is the JWT URN rather than the generic access_token URN.
+ String ISSUED_TOKEN_TYPE_JWT_VALUE = "urn:ietf:params:oauth:token-type:jwt";
String REFRESH_TOKEN_TTL= "refresh.token.ttl";
long REFRESH_TOKEN_TTL_DEFAULT = 86400000L; // 1 day
String CODE_RESPONSE_TYPE = RESPONSE_TYPE + "=" + CODE;