Cookie token store not working in Spring Security adapter

Co-authored-by: scranen <scranen@gmail.com>
Co-authored-by: rainerfrey <frey.rainer@gmail.com>
Co-authored-by: pedroigor <pigor.craveiro@gmail.com>
This commit is contained in:
scranen 2017-07-02 16:01:18 +02:00 committed by Stian Thorgersen
parent 25511d4dbf
commit 2d3f771b70
14 changed files with 399 additions and 19 deletions

View file

@ -94,7 +94,17 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
}
}
/**
* Redirects to the login page. If HTTP sessions are disabled, the redirect URL is saved in a
* cookie now, to be retrieved by the {@link KeycloakAuthenticationSuccessHandler} or the
* {@link KeycloakAuthenticationFailureHandler} when the login sequence completes.
*/
protected void commenceLoginRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
if (request.getSession(false) == null && KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request) == null) {
// If no session exists yet at this point, then apparently the redirect URL is not
// stored in a session. We'll store it in a cookie instead.
response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(request.getRequestURI()));
}
String contextAwareLoginUri = request.getContextPath() + loginUri;
log.debug("Redirecting to login URI {}", contextAwareLoginUri);
response.sendRedirect(contextAwareLoginUri);

View file

@ -38,6 +38,9 @@ public class KeycloakAuthenticationFailureHandler implements AuthenticationFailu
// 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()) {
if (KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request) != null) {
response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(null));
}
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unable to authenticate using the Authorization header");
} else {
if (200 <= response.getStatus() && response.getStatus() < 300) {

View file

@ -0,0 +1,66 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.authentication;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
/**
* Wrapper for an authentication success handler that sends a redirect if a redirect URL was set in
* a cookie.
*
* @author <a href="mailto:scranen@gmail.com">Sjoerd Cranen</a>
*
* @see KeycloakCookieBasedRedirect
* @see KeycloakAuthenticationEntryPoint#commenceLoginRedirect
*/
public class KeycloakAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger LOG = LoggerFactory.getLogger(KeycloakAuthenticationSuccessHandler.class);
private final AuthenticationSuccessHandler fallback;
public KeycloakAuthenticationSuccessHandler(AuthenticationSuccessHandler fallback) {
this.fallback = fallback;
}
@Override
public void onAuthenticationSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String location = KeycloakCookieBasedRedirect.getRedirectUrlFromCookie(request);
if (location == null) {
if (fallback != null) {
fallback.onAuthenticationSuccess(request, response, authentication);
}
} else {
try {
response.addCookie(KeycloakCookieBasedRedirect.createCookieFromRedirectUrl(null));
response.sendRedirect(location);
} catch (IOException e) {
LOG.warn("Unable to redirect user after login", e);
}
}
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.authentication;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* Utility class that provides methods to create and retrieve cookies used for login redirects.
*
* @author <a href="mailto:scranen@gmail.com">Sjoerd Cranen</a>
*/
public final class KeycloakCookieBasedRedirect {
private static final String REDIRECT_COOKIE = "KC_REDIRECT";
private KeycloakCookieBasedRedirect() {}
/**
* Checks if a cookie with name {@value REDIRECT_COOKIE} exists, and if so, returns its value.
* If multiple cookies of the same name exist, the value of the first cookie is returned.
*
* @param request the request to retrieve the cookie from.
* @return the value of the cookie, if it exists, or else {@code null}.
*/
public static String getRedirectUrlFromCookie(HttpServletRequest request) {
if (request.getCookies() == null) {
return null;
}
for (Cookie cookie : request.getCookies()) {
if (REDIRECT_COOKIE.equals(cookie.getName())) {
return cookie.getValue();
}
}
return null;
}
/**
* Creates a cookie with name {@value REDIRECT_COOKIE} and the given URL as value.
*
* @param url the value that the cookie should have. If {@code null}, a cookie is created that
* expires immediately and has an empty string as value.
* @return a cookie that can be added to a response.
*/
public static Cookie createCookieFromRedirectUrl(String url) {
Cookie cookie = new Cookie(REDIRECT_COOKIE, url == null ? "" : url);
cookie.setHttpOnly(true);
cookie.setPath("/");
if (url == null) {
cookie.setMaxAge(0);
}
return cookie;
}
}

View file

@ -22,7 +22,9 @@ import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
import org.keycloak.adapters.springsecurity.token.AdapterTokenStoreFactory;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.adapters.springsecurity.token.SpringSecurityAdapterTokenStoreFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
@ -43,12 +45,17 @@ public class KeycloakLogoutHandler implements LogoutHandler {
private static final Logger log = LoggerFactory.getLogger(KeycloakLogoutHandler.class);
private AdapterDeploymentContext adapterDeploymentContext;
private AdapterTokenStoreFactory adapterTokenStoreFactory = new SpringSecurityAdapterTokenStoreFactory();
public KeycloakLogoutHandler(AdapterDeploymentContext adapterDeploymentContext) {
Assert.notNull(adapterDeploymentContext);
this.adapterDeploymentContext = adapterDeploymentContext;
}
public void setAdapterTokenStoreFactory(AdapterTokenStoreFactory adapterTokenStoreFactory) {
this.adapterTokenStoreFactory = adapterTokenStoreFactory;
}
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
if (authentication == null) {
@ -66,6 +73,7 @@ public class KeycloakLogoutHandler implements LogoutHandler {
protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response, KeycloakAuthenticationToken authenticationToken) {
HttpFacade facade = new SimpleHttpFacade(request, response);
KeycloakDeployment deployment = adapterDeploymentContext.resolveDeployment(facade);
adapterTokenStoreFactory.createAdapterTokenStore(deployment, request, response).logout();
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authenticationToken.getAccount().getKeycloakSecurityContext();
session.logout(deployment);
}

View file

@ -42,7 +42,6 @@ import org.springframework.security.config.annotation.web.servlet.configuration.
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
/**
@ -119,7 +118,7 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), LogoutFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())

View file

@ -0,0 +1,45 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.filter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.constants.AdapterConstants;
import org.springframework.security.web.util.matcher.RequestMatcher;
/**
* Matches a request if it contains a {@value AdapterConstants#KEYCLOAK_ADAPTER_STATE_COOKIE}
* cookie.
*
* @author <a href="mailto:scranen@gmail.com">Sjoerd Cranen</a>
*/
public class AdapterStateCookieRequestMatcher implements RequestMatcher {
@Override
public boolean matches(HttpServletRequest request) {
if (request.getCookies() == null) {
return false;
}
for (Cookie cookie: request.getCookies()) {
if (AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE.equals(cookie.getName())) {
return true;
}
}
return false;
}
}

View file

@ -33,7 +33,9 @@ import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationFailureHandler;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationSuccessHandler;
import org.keycloak.adapters.springsecurity.authentication.RequestAuthenticatorFactory;
import org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticatorFactory;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
@ -52,6 +54,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
@ -65,18 +68,18 @@ import org.springframework.util.Assert;
* @version $Revision: 1 $
*/
public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter implements ApplicationContextAware {
public static final String DEFAULT_LOGIN_URL = "/sso/login";
public static final String AUTHORIZATION_HEADER = "Authorization";
/**
* Request matcher that matches requests to the {@link KeycloakAuthenticationEntryPoint#DEFAULT_LOGIN_URI default login URI}
* and any request with a <code>Authorization</code> header.
* and any request with a <code>Authorization</code> header or an {@link AdapterStateCookieRequestMatcher adapter state cookie}.
*/
public static final RequestMatcher DEFAULT_REQUEST_MATCHER =
new OrRequestMatcher(
new AntPathRequestMatcher(DEFAULT_LOGIN_URL),
new AntPathRequestMatcher(KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI),
new RequestHeaderRequestMatcher(AUTHORIZATION_HEADER),
new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN)
new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN),
new AdapterStateCookieRequestMatcher()
);
private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticationProcessingFilter.class);
@ -97,6 +100,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
public KeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
this(authenticationManager, DEFAULT_REQUEST_MATCHER);
setAuthenticationFailureHandler(new KeycloakAuthenticationFailureHandler());
setAuthenticationSuccessHandler(new KeycloakAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler()));
}
/**
@ -143,7 +147,7 @@ public class KeycloakAuthenticationProcessingFilter extends AbstractAuthenticati
// using Spring authenticationFailureHandler
deployment.setDelegateBearerErrorResponseSending(true);
AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request);
AdapterTokenStore tokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, request, response);
RequestAuthenticator authenticator
= requestAuthenticatorFactory.createRequestAuthenticator(facade, request, deployment, tokenStore, -1);

View file

@ -73,7 +73,8 @@ public class KeycloakSecurityContextRequestFilter extends GenericFilterBean impl
// just in case session got serialized
if (refreshableSecurityContext.getDeployment()==null) {
log.trace("Recreating missing deployment and related fields in deserialized context");
AdapterTokenStore adapterTokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, (HttpServletRequest) request);
AdapterTokenStore adapterTokenStore = adapterTokenStoreFactory.createAdapterTokenStore(deployment, (HttpServletRequest) request,
(HttpServletResponse) response);
refreshableSecurityContext.setCurrentRequestInfo(deployment, adapterTokenStore);
}

View file

@ -17,6 +17,7 @@
package org.keycloak.adapters.springsecurity.token;
import javax.servlet.http.HttpServletResponse;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
@ -34,10 +35,11 @@ public interface AdapterTokenStoreFactory {
*
* @param deployment the <code>KeycloakDeployment</code> (required)
* @param request the current <code>HttpServletRequest</code> (required)
* @param response the current <code>HttpServletResponse</code> (required when using cookies)
*
* @return a new <code>AdapterTokenStore</code> for the given <code>deployment</code> and <code>request</code>
* @throws IllegalArgumentException if either the <code>deployment</code> or <code>request</code> is <code>null</code>
* @return a new <code>AdapterTokenStore</code> for the given <code>deployment</code>, <code>request</code> and <code>response</code>
* @throws IllegalArgumentException if any required parameter is <code>null</code>
*/
AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request);
AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request, HttpServletResponse response);
}

View file

@ -19,8 +19,11 @@ package org.keycloak.adapters.springsecurity.token;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.enums.TokenStore;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* {@link AdapterTokenStoreFactory} that returns a new {@link SpringSecurityTokenStore} for each request.
@ -30,7 +33,11 @@ import javax.servlet.http.HttpServletRequest;
public class SpringSecurityAdapterTokenStoreFactory implements AdapterTokenStoreFactory {
@Override
public AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request) {
public AdapterTokenStore createAdapterTokenStore(KeycloakDeployment deployment, HttpServletRequest request, HttpServletResponse response) {
Assert.notNull(deployment, "KeycloakDeployment is required");
if (deployment.getTokenStore() == TokenStore.COOKIE) {
return new SpringSecurityCookieTokenStore(deployment, request, response);
}
return new SpringSecurityTokenStore(deployment, request);
}
}

View file

@ -0,0 +1,141 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.adapters.springsecurity.token;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.CookieTokenStore;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OIDCHttpFacade;
import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
/**
* Extension of {@link SpringSecurityTokenStore} that stores the obtains tokens in a cookie.
*
* @author <a href="mailto:scranen@gmail.com">Sjoerd Cranen</a>
*/
public class SpringSecurityCookieTokenStore extends SpringSecurityTokenStore {
private final Logger logger = LoggerFactory.getLogger(SpringSecurityCookieTokenStore.class);
private final KeycloakDeployment deployment;
private final HttpFacade facade;
private volatile boolean cookieChecked = false;
public SpringSecurityCookieTokenStore(
KeycloakDeployment deployment,
HttpServletRequest request,
HttpServletResponse response) {
super(deployment, request);
Assert.notNull(response, "HttpServletResponse is required");
this.deployment = deployment;
this.facade = new SimpleHttpFacade(request, response);
}
@Override
public void checkCurrentToken() {
final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal =
checkPrincipalFromCookie();
if (principal != null) {
final RefreshableKeycloakSecurityContext securityContext =
principal.getKeycloakSecurityContext();
KeycloakSecurityContext current = ((OIDCHttpFacade) facade).getSecurityContext();
if (current != null) {
securityContext.setAuthorizationContext(current.getAuthorizationContext());
}
final Set<String> roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
final OidcKeycloakAccount account =
new SimpleKeycloakAccount(principal, roles, securityContext);
SecurityContextHolder.getContext()
.setAuthentication(new KeycloakAuthenticationToken(account, false));
} else {
super.checkCurrentToken();
}
cookieChecked = true;
}
@Override
public boolean isCached(RequestAuthenticator authenticator) {
if (!cookieChecked) {
checkCurrentToken();
}
return super.isCached(authenticator);
}
@Override
public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) {
super.refreshCallback(securityContext);
CookieTokenStore.setTokenCookie(deployment, facade, securityContext);
}
@Override
public void saveAccountInfo(OidcKeycloakAccount account) {
super.saveAccountInfo(account);
RefreshableKeycloakSecurityContext securityContext =
(RefreshableKeycloakSecurityContext) account.getKeycloakSecurityContext();
CookieTokenStore.setTokenCookie(deployment, facade, securityContext);
}
@Override
public void logout() {
CookieTokenStore.removeCookie(deployment, facade);
super.logout();
}
/**
* Verify if we already have authenticated and active principal in cookie. Perform refresh if
* it's not active
*
* @return valid principal
*/
private KeycloakPrincipal<RefreshableKeycloakSecurityContext> checkPrincipalFromCookie() {
KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal =
CookieTokenStore.getPrincipalFromCookie(deployment, facade, this);
if (principal == null) {
logger.debug("Account was not in cookie or was invalid");
return null;
}
RefreshableKeycloakSecurityContext session = principal.getKeycloakSecurityContext();
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return principal;
boolean success = session.refreshExpiredToken(false);
if (success && session.isActive()) {
refreshCallback(session);
return principal;
}
logger.debug(
"Cleanup and expire cookie for user {} after failed refresh", principal.getName());
CookieTokenStore.removeCookie(deployment, facade);
return null;
}
}

View file

@ -27,6 +27,7 @@ import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
import org.keycloak.adapters.springsecurity.account.KeycloakRole;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationFailureHandler;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.common.enums.SslRequired;
@ -50,8 +51,6 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
@ -107,6 +106,7 @@ public class KeycloakAuthenticationProcessingFilterTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
request = spy(new MockHttpServletRequest());
request.setRequestURI("http://host");
filter = new KeycloakAuthenticationProcessingFilter(authenticationManager);
keycloakFailureHandler = new KeycloakAuthenticationFailureHandler();
@ -151,6 +151,7 @@ public class KeycloakAuthenticationProcessingFilterTest {
@Test
public void testSuccessfulAuthenticationInteractive() throws Exception {
request.setRequestURI("http://host" + KeycloakAuthenticationEntryPoint.DEFAULT_LOGIN_URI + "?query");
Authentication authentication = new KeycloakAuthenticationToken(keycloakAccount, true, authorities);
filter.successfulAuthentication(request, response, chain, authentication);

View file

@ -21,13 +21,15 @@ import org.junit.Before;
import org.junit.Test;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.spi.AdapterSessionStore;
import org.keycloak.enums.TokenStore;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
/**
* Spring Security adapter token store factory tests.
@ -42,6 +44,9 @@ public class SpringSecurityAdapterTokenStoreFactoryTest {
@Mock
private HttpServletRequest request;
@Mock
private HttpServletResponse response;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@ -49,18 +54,37 @@ public class SpringSecurityAdapterTokenStoreFactoryTest {
@Test
public void testCreateAdapterTokenStore() throws Exception {
AdapterSessionStore store = factory.createAdapterTokenStore(deployment, request);
assertNotNull(store);
when(deployment.getTokenStore()).thenReturn(TokenStore.SESSION);
AdapterSessionStore store = factory.createAdapterTokenStore(deployment, request, response);
assertTrue(store instanceof SpringSecurityTokenStore);
}
@Test
public void testCreateAdapterTokenStoreUsingCookies() throws Exception {
when(deployment.getTokenStore()).thenReturn(TokenStore.COOKIE);
AdapterSessionStore store = factory.createAdapterTokenStore(deployment, request, response);
assertTrue(store instanceof SpringSecurityCookieTokenStore);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateAdapterTokenStoreNullDeployment() throws Exception {
factory.createAdapterTokenStore(null, request);
factory.createAdapterTokenStore(null, request, response);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateAdapterTokenStoreNullRequest() throws Exception {
factory.createAdapterTokenStore(deployment, null);
factory.createAdapterTokenStore(deployment, null, response);
}
@Test
public void testCreateAdapterTokenStoreNullResponse() throws Exception {
when(deployment.getTokenStore()).thenReturn(TokenStore.SESSION);
factory.createAdapterTokenStore(deployment, request, null);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateAdapterTokenStoreNullResponseUsingCookies() throws Exception {
when(deployment.getTokenStore()).thenReturn(TokenStore.COOKIE);
factory.createAdapterTokenStore(deployment, request, null);
}
}