Use backchannel logout for Spring Security SSO
Use backchannel logout for Keycloak's Spring Security adapter single sign-out to allow Spring Security's logout complete handler to fire.
This commit is contained in:
parent
aaebcd074e
commit
a7bfae2f56
1 changed files with 11 additions and 16 deletions
|
@ -1,14 +1,16 @@
|
|||
package org.keycloak.adapters.springsecurity.authentication;
|
||||
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
|
||||
import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
|
||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -22,7 +24,6 @@ import java.io.IOException;
|
|||
*/
|
||||
public class KeycloakLogoutHandler implements LogoutHandler {
|
||||
|
||||
public static final String SSO_LOGOUT_COMPLETE_PARAM = "sso_complete";
|
||||
private static final Logger log = LoggerFactory.getLogger(KeycloakLogoutHandler.class);
|
||||
|
||||
private AdapterDeploymentContextBean deploymentContextBean;
|
||||
|
@ -40,30 +41,24 @@ public class KeycloakLogoutHandler implements LogoutHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Boolean.valueOf(request.getParameter(SSO_LOGOUT_COMPLETE_PARAM))) {
|
||||
// already logged out
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
handleSingleSignOut(request, response);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to redirect to SSO url!", e);
|
||||
throw new IllegalStateException("Unable to make logout admin request!", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String createRedirectUrl(HttpServletRequest request) {
|
||||
|
||||
return UriComponentsBuilder.fromHttpUrl(request.getRequestURL().toString())
|
||||
.replaceQueryParam(SSO_LOGOUT_COMPLETE_PARAM, true).build().toUriString();
|
||||
}
|
||||
|
||||
protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
|
||||
KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
KeycloakDeployment deployment = deploymentContextBean.getDeployment();
|
||||
String redirectUrl = createRedirectUrl(request);
|
||||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authentication.getAccount().getKeycloakSecurityContext();
|
||||
|
||||
response.sendRedirect(deployment.getLogoutUrl().queryParam("redirect_uri", redirectUrl).build().toASCIIString());
|
||||
try {
|
||||
session.logout(deployment);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to complete Keycloak single sign out", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue