From b3f142d71530027f41f510e7cabed61d1209c326 Mon Sep 17 00:00:00 2001 From: Thomas Raehalme Date: Mon, 17 Aug 2015 18:05:49 +0300 Subject: [PATCH] KeycloakAuthenticationProcessingFilter now handles Basic Authentication the same way as Bearer token. --- ...eycloakAuthenticationProcessingFilter.java | 20 ++++++++-- ...oakAuthenticationProcessingFilterTest.java | 40 +++++++++++++++++-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java index cf5f373fcf..f31478e3a7 100644 --- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java +++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilter.java @@ -144,17 +144,29 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati return authValue != null && authValue.startsWith("Bearer"); } + /** + * Returns true if the request was made with a Basic authentication authorization header. + * + * @param request the current HttpServletRequest + * @return true if the request was made with a Basic authentication authorization header; + * false otherwise. + */ + protected boolean isBasicAuthRequest(HttpServletRequest request) { + String authValue = request.getHeader(AUTHORIZATION_HEADER); + return authValue != null && authValue.startsWith("Basic"); + } + @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { - if (!this.isBearerTokenRequest(request)) { + if (!(this.isBearerTokenRequest(request) || this.isBasicAuthRequest(request))) { super.successfulAuthentication(request, response, chain, authResult); return; } if (log.isDebugEnabled()) { - log.debug("Authentication success using bearer token. Updating SecurityContextHolder to contain: {}", authResult); + log.debug("Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: {}", authResult); } SecurityContextHolder.getContext().setAuthentication(authResult); @@ -176,9 +188,9 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { - if (this.isBearerTokenRequest(request)) { + if (this.isBearerTokenRequest(request) || this.isBasicAuthRequest(request)) { SecurityContextHolder.clearContext(); - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Unable to authenticate bearer token"); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Unable to authenticate bearer token/basic authentication"); return; } diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java index 45420339db..034e212001 100644 --- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java +++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java @@ -94,10 +94,17 @@ public class KeycloakAuthenticationProcessingFilterTest { @Test public void testIsBearerTokenRequest() throws Exception { assertFalse(filter.isBearerTokenRequest(request)); - this.setAuthHeader(request); + this.setBearerAuthHeader(request); assertTrue(filter.isBearerTokenRequest(request)); } + @Test + public void testIsBasicAuthRequest() throws Exception { + assertFalse(filter.isBasicAuthRequest(request)); + this.setBasicAuthHeader(request); + assertTrue(filter.isBasicAuthRequest(request)); + } + @Test public void testSuccessfulAuthenticationInteractive() throws Exception { Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, authorities); @@ -110,7 +117,18 @@ public class KeycloakAuthenticationProcessingFilterTest { @Test public void testSuccessfulAuthenticationBearer() throws Exception { Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, authorities); - this.setAuthHeader(request); + this.setBearerAuthHeader(request); + filter.successfulAuthentication(request, response, chain, authentication); + + verify(chain).doFilter(eq(request), eq(response)); + verify(successHandler, never()).onAuthenticationSuccess(any(HttpServletRequest.class), any(HttpServletResponse.class), + any(Authentication.class)); + } + + @Test + public void testSuccessfulAuthenticationBasicAuth() throws Exception { + Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, authorities); + this.setBasicAuthHeader(request); filter.successfulAuthentication(request, response, chain, authentication); verify(chain).doFilter(eq(request), eq(response)); @@ -128,7 +146,17 @@ public class KeycloakAuthenticationProcessingFilterTest { @Test public void testUnsuccessfulAuthenticatioBearer() throws Exception { AuthenticationException exception = new BadCredentialsException("OOPS"); - this.setAuthHeader(request); + this.setBearerAuthHeader(request); + filter.unsuccessfulAuthentication(request, response, exception); + verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), anyString()); + verify(failureHandler, never()).onAuthenticationFailure(any(HttpServletRequest.class), any(HttpServletResponse.class), + any(AuthenticationException.class)); + } + + @Test + public void testUnsuccessfulAuthenticatioBasicAuth() throws Exception { + AuthenticationException exception = new BadCredentialsException("OOPS"); + this.setBasicAuthHeader(request); filter.unsuccessfulAuthentication(request, response, exception); verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), anyString()); verify(failureHandler, never()).onAuthenticationFailure(any(HttpServletRequest.class), any(HttpServletResponse.class), @@ -145,8 +173,12 @@ public class KeycloakAuthenticationProcessingFilterTest { filter.setContinueChainBeforeSuccessfulAuthentication(true); } - private void setAuthHeader(MockHttpServletRequest request) { + private void setBearerAuthHeader(MockHttpServletRequest request) { request.addHeader(KeycloakAuthenticationProcessingFilter.AUTHORIZATION_HEADER, "Bearer " + UUID.randomUUID().toString()); } + private void setBasicAuthHeader(MockHttpServletRequest request) { + request.addHeader(KeycloakAuthenticationProcessingFilter.AUTHORIZATION_HEADER, "Basic " + UUID.randomUUID().toString()); + } + }