This is an automated email from the ASF dual-hosted git repository.
chibenwa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new a0e591ad0b JAMES-4195 Validate in introspection that OIDC tokens are
active (#3139)
a0e591ad0b is described below
commit a0e591ad0b864c5781e1b45c97486de82ab13962
Author: Benoit TELLIER <[email protected]>
AuthorDate: Thu Aug 27 10:03:45 2026 +0700
JAMES-4195 Validate in introspection that OIDC tokens are active (#3139)
Credit: MopMonk AI [email protected]
---
.../contract/OidcAuthenticationContract.java | 26 ++++++++++++++++++++++
server/protocols/jwt/pom.xml | 5 +++++
.../james/jwt/oidc/OidcEndpointsInfoResolver.java | 4 ++++
3 files changed, 35 insertions(+)
diff --git
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/OidcAuthenticationContract.java
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/OidcAuthenticationContract.java
index 9d94666729..8438a8d354 100644
---
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/OidcAuthenticationContract.java
+++
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/OidcAuthenticationContract.java
@@ -253,6 +253,32 @@ public abstract class OidcAuthenticationContract {
.statusCode(SC_UNAUTHORIZED);
}
+ @Tag(CategoryTags.BASIC_FEATURE)
+ @Test
+ void shouldRejectRevokedToken() {
+ // A revoked token: userinfo still answers, but introspection reports
the token as inactive (RFC 7662)
+ mockUserInfo(BOB().asString());
+ mockJsonResponse(INTROSPECT_TOKEN_URI_PATH, """
+ {
+ "exp": %d,
+ "scope": "openid email profile",
+ "client_id": "james",
+ "active": false,
+ "aud": "%s",
+ "sub": "james-user",
+ "sid": "%s",
+ "iss": "https://sso.example.com"
+ }""".formatted(TOKEN_EXPIRATION_TIME, primaryAudience(), SID),
SC_OK);
+
+ given()
+ .headers(getHeadersWith(authHeader))
+ .body(ECHO_REQUEST_OBJECT())
+ .when()
+ .post()
+ .then()
+ .statusCode(SC_UNAUTHORIZED);
+ }
+
@Tag(CategoryTags.BASIC_FEATURE)
@Test
void shouldRejectBadAudience() {
diff --git a/server/protocols/jwt/pom.xml b/server/protocols/jwt/pom.xml
index bf9a8eb452..294bc9877b 100644
--- a/server/protocols/jwt/pom.xml
+++ b/server/protocols/jwt/pom.xml
@@ -48,6 +48,11 @@
<groupId>${james.groupId}</groupId>
<artifactId>metrics-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>metrics-tests</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${james.groupId}</groupId>
<artifactId>testing-base</artifactId>
diff --git
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/oidc/OidcEndpointsInfoResolver.java
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/oidc/OidcEndpointsInfoResolver.java
index fe539686a0..7a3d56c34e 100644
---
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/oidc/OidcEndpointsInfoResolver.java
+++
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/oidc/OidcEndpointsInfoResolver.java
@@ -78,6 +78,10 @@ public class OidcEndpointsInfoResolver implements
TokenInfoResolver {
UserinfoResponse userInfo = tokenInfos.getT1();
TokenIntrospectionResponse introspectInfo = tokenInfos.getT2();
+ if (!introspectInfo.active()) {
+ return Mono.error(new TokenIntrospectionException("Invalid
OIDC token: the token is not active"));
+ }
+
Username sub =
Username.of(userInfo.claimByPropertyName(oidcClaim)
.orElseThrow(() -> new UserInfoCheckException("Invalid
OIDC token: userinfo needs to include " + oidcClaim + " claim")));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]