From cb43e3d763b27a85938aeac7938b201a78d30316 Mon Sep 17 00:00:00 2001 From: Sjoerd Cranen Date: Mon, 16 Oct 2017 09:34:58 +0200 Subject: [PATCH] KEYCLOAK-5191 Prevent exception in KeycloakAuthenticationFailureHandler (#4319) * KEYCLOAK-5191 Don't attempt to send 401 when response is already committed * KEYCLOAK-5191 Defend against configuration errors by preventing 2xx response after authentication failure --- .../KeycloakAuthenticationFailureHandler.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java index fcff678d5b..5bdd3e18f6 100644 --- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java +++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationFailureHandler.java @@ -17,14 +17,13 @@ package org.keycloak.adapters.springsecurity.authentication; -import java.io.IOException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import java.io.IOException; /** * To return the forbidden code with the corresponding message. @@ -36,6 +35,14 @@ public class KeycloakAuthenticationFailureHandler implements AuthenticationFailu @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unable to authenticate using the Authorization header"); + // Check that the response was not committed yet (this may happen when another + // part of the Keycloak adapter sends a challenge or a redirect). + if (!response.isCommitted()) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unable to authenticate using the Authorization header"); + } else { + if (200 <= response.getStatus() && response.getStatus() < 300) { + throw new RuntimeException("Success response was committed while authentication failed!", exception); + } + } } }