From 5ae60f351373ac690ed7b553f64e32f557300db5 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Tue, 16 Dec 2025 14:41:14 +0100 Subject: [PATCH] Fix NPE in JWT authenticators (#44941) Closes #44940 Signed-off-by: stianst --- .../client/FederatedJWTClientAuthenticator.java | 6 ++++-- .../client/JWTClientAuthenticator.java | 14 ++++++++------ .../client/JWTClientSecretAuthenticator.java | 14 ++++++++------ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java index 3ef2177c9c3..af0a521a364 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java @@ -23,6 +23,7 @@ import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.provider.EnvironmentDependentProviderFactory; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.representations.JsonWebToken; import org.keycloak.services.resources.IdentityBrokerService; import org.jboss.logging.Logger; @@ -79,13 +80,14 @@ public class FederatedJWTClientAuthenticator extends AbstractClientAuthenticator context.attempted(); ClientAssertionState clientAssertionState = context.getState(ClientAssertionState.class, ClientAssertionState.supplier()); - if (clientAssertionState == null || clientAssertionState.getClientAssertionType() == null) { return; } + JsonWebToken jwt = clientAssertionState.getToken(); + // Ignore for self-signed client assertions - if (Objects.equals(clientAssertionState.getToken().getIssuer(), clientAssertionState.getToken().getSubject())) { + if (jwt != null && Objects.equals(jwt.getIssuer(), jwt.getSubject())) { return; } diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java index a54090f68e8..e8273a35eec 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java @@ -68,13 +68,15 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator { ClientAssertionState clientAssertionState = context.getState(ClientAssertionState.class, ClientAssertionState.supplier()); JsonWebToken jwt = clientAssertionState.getToken(); - // Ignore for client assertions signed by third-parties - if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) { - return; - } + if (jwt != null) { + // Ignore for client assertions signed by third-parties + if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) { + return; + } - if (clientAssertionState.getClient() == null) { - clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject())); + if (clientAssertionState.getClient() == null) { + clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject())); + } } JWTClientValidator validator = new JWTClientValidator(context, this::verifySignature, getId()); diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java index dad5e3b7d71..505e07a6071 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java @@ -59,13 +59,15 @@ public class JWTClientSecretAuthenticator extends AbstractClientAuthenticator { ClientAssertionState clientAssertionState = context.getState(ClientAssertionState.class, ClientAssertionState.supplier()); JsonWebToken jwt = clientAssertionState.getToken(); - // Ignore for client assertions signed by third-parties - if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) { - return; - } + if (jwt != null) { + // Ignore for client assertions signed by third-parties + if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) { + return; + } - if (clientAssertionState.getClient() == null) { - clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject())); + if (clientAssertionState.getClient() == null) { + clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject())); + } } JWTClientValidator validator = new JWTClientValidator(context, this::verifySignature, getId());