Remove keycloak-undertow-adapter-spi

closes #31489

Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
mposolda 2024-07-22 17:09:59 +02:00 committed by Alexander Schwartz
parent d9555e4c9f
commit 59e1b4271a
10 changed files with 0 additions and 874 deletions

View file

@ -32,7 +32,6 @@
<modules>
<module>adapter-spi</module>
<module>undertow-adapter-spi</module>
<module>jboss-adapter-core</module>
</modules>
</project>

View file

@ -1,73 +0,0 @@
<?xml version="1.0"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>999.0.0-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<name>Keycloak Undertow Integration SPI</name>
<description/>
<properties>
<!-- We still need to support EAP 8, set the Java version to 11. -->
<maven.compiler.release>11</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,68 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.Session;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.servlet.spec.HttpSessionImpl;
import io.undertow.servlet.spec.ServletContextImpl;
import java.lang.reflect.Method;
import java.security.AccessController;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ChangeSessionId {
/**
* This is a hack to be backward compatible between Undertow 1.3+ and versions lower. In Undertow 1.3, a new
* switch was added setChangeSessionIdOnLogin, this screws up session management for keycloak as after the session id
* is uploaded to Keycloak, undertow changes the session id and it can't be invalidated.
*
* @param deploymentInfo
*/
public static void turnOffChangeSessionIdOnLogin(DeploymentInfo deploymentInfo) {
try {
Method method = DeploymentInfo.class.getMethod("setChangeSessionIdOnLogin", boolean.class);
method.invoke(deploymentInfo, false);
} catch (Exception ignore) {
}
}
public static String changeSessionId(HttpServerExchange exchange, boolean create) {
final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
ServletContextImpl currentServletContext = sc.getCurrentServletContext();
HttpSessionImpl session = currentServletContext.getSession(exchange, create);
if (session == null) {
return null;
}
Session underlyingSession;
if(System.getSecurityManager() == null) {
underlyingSession = session.getSession();
} else {
underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
}
return underlyingSession.changeSessionId(exchange, currentServletContext.getSessionConfig());
}
}

View file

@ -1,82 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.Session;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.servlet.spec.HttpSessionImpl;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.security.AccessController;
/**
* Saved servlet request.
*
* Note bill burke: I had to fork this because Undertow was automatically restoring the request before the code could be
* processed and redirected.
*
* CachedAuthenticatedSessionHandler was restoring the request before the authentication manager could read the code from the URI
* Originally, I copied SavedRequest as is, but there are type mismatches between Undertow 1.1.1 and 1.3.10.
* So, trySaveRequest calls the same undertow version, removes the saved request, stores it in a different session attribute,
* then restores the old attribute later
*
*
* @author Stuart Douglas
*/
public class SavedRequest implements Serializable {
private static final String SESSION_KEY = SavedRequest.class.getName();
public static void trySaveRequest(final HttpServerExchange exchange) {
io.undertow.servlet.util.SavedRequest.trySaveRequest(exchange);
final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
Session underlyingSession;
if(System.getSecurityManager() == null) {
underlyingSession = session.getSession();
} else {
underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
}
io.undertow.servlet.util.SavedRequest request = (io.undertow.servlet.util.SavedRequest) underlyingSession.removeAttribute(io.undertow.servlet.util.SavedRequest.class.getName());
if (request != null) underlyingSession.setAttribute(SESSION_KEY, request);
}
public static void tryRestoreRequest(final HttpServerExchange exchange, HttpSession session) {
if(session instanceof HttpSessionImpl) {
Session underlyingSession;
if(System.getSecurityManager() == null) {
underlyingSession = ((HttpSessionImpl) session).getSession();
} else {
underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
}
io.undertow.servlet.util.SavedRequest request = (io.undertow.servlet.util.SavedRequest) underlyingSession.removeAttribute(SESSION_KEY);
if (request != null) {
underlyingSession.setAttribute(io.undertow.servlet.util.SavedRequest.class.getName(), request);
io.undertow.servlet.util.SavedRequest.tryRestoreRequest(exchange, session);
}
}
}
}

View file

@ -1,96 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.HttpServerExchange;
import io.undertow.servlet.handlers.ServletRequestContext;
import org.keycloak.adapters.spi.AuthenticationError;
import org.keycloak.adapters.spi.LogoutError;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ServletHttpFacade extends UndertowHttpFacade {
protected HttpServletRequest request;
protected HttpServletResponse response;
public ServletHttpFacade(HttpServerExchange exchange) {
super(exchange);
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
request = (HttpServletRequest)servletRequestContext.getServletRequest();
response = (HttpServletResponse)servletRequestContext.getServletResponse();
}
protected class RequestFacade extends UndertowHttpFacade.RequestFacade {
@Override
public String getFirstParam(String param) {
return request.getParameter(param);
}
@Override
public void setError(AuthenticationError error) {
request.setAttribute(AuthenticationError.class.getName(), error);
}
@Override
public void setError(LogoutError error) {
request.setAttribute(LogoutError.class.getName(), error);
}
}
protected class ResponseFacade extends UndertowHttpFacade.ResponseFacade {
// can't call sendError from a challenge. Undertow ends up calling send error.
/*
@Override
public void sendError(int code) {
try {
response.sendError(code);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void sendError(int code, String message) {
try {
response.sendError(code, message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
*/
}
@Override
public Response getResponse() {
return new ResponseFacade();
}
@Override
public Request getRequest() {
return new RequestFacade();
}
}

View file

@ -1,48 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.session.SessionManager;
import org.keycloak.adapters.spi.UserSessionManagement;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class SessionManagementBridge implements UserSessionManagement {
protected UndertowUserSessionManagement userSessionManagement;
protected SessionManager sessionManager;
public SessionManagementBridge(UndertowUserSessionManagement userSessionManagement, SessionManager sessionManager) {
this.userSessionManagement = userSessionManagement;
this.sessionManager = sessionManager;
}
@Override
public void logoutAll() {
userSessionManagement.logoutAll(sessionManager);
}
@Override
public void logoutHttpSessions(List<String> ids) {
userSessionManagement.logoutHttpSessions(sessionManager, ids);
}
}

View file

@ -1,298 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.CookieImpl;
import io.undertow.server.handlers.form.FormData;
import io.undertow.server.handlers.form.FormData.FormValue;
import io.undertow.server.handlers.form.FormDataParser;
import io.undertow.server.handlers.form.FormParserFactory;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.util.AttachmentKey;
import io.undertow.util.Headers;
import io.undertow.util.HttpString;
import org.keycloak.adapters.spi.AuthenticationError;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.LogoutError;
import org.keycloak.common.util.KeycloakUriBuilder;
import javax.security.cert.X509Certificate;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Deque;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UndertowHttpFacade implements HttpFacade {
public static final AttachmentKey<AuthenticationError> AUTH_ERROR_ATTACHMENT_KEY = AttachmentKey.create(AuthenticationError.class);
public static final AttachmentKey<LogoutError> LOGOUT_ERROR_ATTACHMENT_KEY = AttachmentKey.create(LogoutError.class);
protected HttpServerExchange exchange;
protected RequestFacade requestFacade = new RequestFacade();
protected ResponseFacade responseFacade = new ResponseFacade();
public UndertowHttpFacade(HttpServerExchange exchange) {
this.exchange = exchange;
}
@Override
public Request getRequest() {
return requestFacade;
}
@Override
public Response getResponse() {
return responseFacade;
}
@Override
public X509Certificate[] getCertificateChain() {
X509Certificate[] chain = new X509Certificate[0];
try {
chain = exchange.getConnection().getSslSessionInfo().getPeerCertificateChain();
} catch (Exception ignore) {
}
return chain;
}
protected class RequestFacade implements Request {
private InputStream inputStream;
private final FormParserFactory formParserFactory = FormParserFactory.builder().build();
private FormData formData;
@Override
public String getURI() {
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(exchange.getRequestURI())
.replaceQuery(exchange.getQueryString());
if (!exchange.isHostIncludedInRequestURI()) uriBuilder.scheme(exchange.getRequestScheme()).host(exchange.getHostAndPort());
return uriBuilder.buildAsString();
}
@Override
public String getRelativePath() {
return exchange.getRelativePath();
}
@Override
public boolean isSecure() {
String protocol = exchange.getRequestScheme();
return protocol.equalsIgnoreCase("https");
}
@Override
public String getFirstParam(String param) {
Deque<String> values = exchange.getQueryParameters().get(param);
if (values != null && !values.isEmpty()) {
return values.getFirst();
}
if (formData == null && "post".equalsIgnoreCase(getMethod())) {
FormDataParser parser = formParserFactory.createParser(exchange);
try {
formData = parser.parseBlocking();
} catch (IOException cause) {
throw new RuntimeException("Failed to parse form parameters", cause);
}
}
if (formData != null) {
Deque<FormValue> formValues = formData.get(param);
if (formValues != null && !formValues.isEmpty()) {
FormValue firstValue = formValues.getFirst();
if (!firstValue.isFile()) {
return firstValue.getValue();
}
}
}
return null;
}
@Override
public String getQueryParamValue(String param) {
Map<String,Deque<String>> queryParameters = exchange.getQueryParameters();
if (queryParameters == null) return null;
Deque<String> strings = queryParameters.get(param);
if (strings == null) return null;
return strings.getFirst();
}
@Override
public Cookie getCookie(String cookieName) {
Map<String, io.undertow.server.handlers.Cookie> requestCookies = exchange.getRequestCookies();
if (requestCookies == null) return null;
io.undertow.server.handlers.Cookie cookie = requestCookies.get(cookieName);
if (cookie == null) return null;
return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath());
}
@Override
public List<String> getHeaders(String name) {
return exchange.getRequestHeaders().get(name);
}
@Override
public String getMethod() {
return exchange.getRequestMethod().toString();
}
@Override
public String getHeader(String name) {
return exchange.getRequestHeaders().getFirst(name);
}
@Override
public InputStream getInputStream() {
return getInputStream(false);
}
@Override
public InputStream getInputStream(boolean buffered) {
if (!exchange.isBlocking()) exchange.startBlocking();
if (inputStream != null) {
return inputStream;
}
if (buffered) {
ServletRequestContext context = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
ServletRequest servletRequest = context.getServletRequest();
inputStream = new BufferedInputStream(exchange.getInputStream());
context.setServletRequest(UndertowHttpServletRequest.setupServletInputStream(servletRequest, inputStream));
return inputStream;
}
return exchange.getInputStream();
}
@Override
public String getRemoteAddr() {
InetSocketAddress sourceAddress = exchange.getSourceAddress();
if (sourceAddress == null) {
return "";
}
InetAddress address = sourceAddress.getAddress();
if (address == null) {
// this is unresolved, so we just return the host name not exactly spec, but if the name should be
// resolved then a PeerNameResolvingHandler should be used and this is probably better than just
// returning null
return sourceAddress.getHostString();
}
return address.getHostAddress();
}
@Override
public void setError(AuthenticationError error) {
exchange.putAttachment(AUTH_ERROR_ATTACHMENT_KEY, error);
}
@Override
public void setError(LogoutError error) {
exchange.putAttachment(LOGOUT_ERROR_ATTACHMENT_KEY, error);
}
}
protected class ResponseFacade implements Response {
@Override
public void setStatus(int status) {
exchange.setResponseCode(status);
}
@Override
public void addHeader(String name, String value) {
exchange.getResponseHeaders().add(new HttpString(name), value);
}
@Override
public void setHeader(String name, String value) {
exchange.getResponseHeaders().put(new HttpString(name), value);
}
@Override
public void resetCookie(String name, String path) {
CookieImpl cookie = new CookieImpl(name, "");
cookie.setMaxAge(0);
cookie.setPath(path);
exchange.setResponseCookie(cookie);
}
@Override
public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) {
CookieImpl cookie = new CookieImpl(name, value);
cookie.setPath(path);
cookie.setDomain(domain);
cookie.setMaxAge(maxAge);
cookie.setSecure(secure);
cookie.setHttpOnly(httpOnly);
exchange.setResponseCookie(cookie);
}
@Override
public OutputStream getOutputStream() {
if (!exchange.isBlocking()) exchange.startBlocking();
return exchange.getOutputStream();
}
@Override
public void sendError(int code) {
exchange.setResponseCode(code);
}
@Override
public void sendError(int code, String message) {
exchange.setResponseCode(code);
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/html");
try {
exchange.getOutputStream().write(message.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
exchange.endExchange();
}
@Override
public void end() {
exchange.endExchange();
}
}
}

View file

@ -1,43 +0,0 @@
/*
* Copyright 2023 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.undertow;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.io.InputStream;
public class UndertowHttpServletRequest {
public static HttpServletRequestWrapper setupServletInputStream(ServletRequest servletRequest, final InputStream inputStream) {
return new HttpServletRequestWrapper((HttpServletRequest) servletRequest) {
@Override
public ServletInputStream getInputStream() {
inputStream.mark(0);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return inputStream.read();
}
};
}
};
}
}

View file

@ -1,160 +0,0 @@
/*
* 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.undertow;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.Session;
import io.undertow.server.session.SessionConfig;
import io.undertow.server.session.SessionListener;
import io.undertow.server.session.SessionManager;
import org.jboss.logging.Logger;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Manages relationship to users and sessions so that forced admin logout can be implemented
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UndertowUserSessionManagement implements SessionListener {
private static final Logger log = Logger.getLogger(UndertowUserSessionManagement.class);
protected volatile boolean registered;
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public void login(SessionManager manager) {
if (!registered) {
manager.registerSessionListener(this);
registered = true;
}
}
/**
* This method runs the given runnable in the current thread if the session manager does not use distributed sessions,
* or in a separate thread if it does. This is to work around:
* <pre>
* org.infinispan.util.concurrent.TimeoutException: ISPN000299: Unable to acquire lock after 15 seconds for key SessionCreationMetaDataKey
* </pre>
* See https://issues.jboss.org/browse/KEYCLOAK-9822
* @param r
*/
private void workaroundIspnDeadlock(final SessionManager manager, Runnable r) {
if (manager.getClass().getName().equals("org.wildfly.clustering.web.undertow.session.DistributableSessionManager")) {
executor.submit(r);
} else {
r.run();
}
}
public void logoutAll(final SessionManager manager) {
final Set<String> allSessions = manager.getAllSessions();
workaroundIspnDeadlock(manager, new Runnable() {
@Override
public void run() {
for (String sessionId : allSessions) logoutSession(manager, sessionId);
}
});
}
public void logoutHttpSessions(final SessionManager manager, final List<String> sessionIds) {
log.debugf("logoutHttpSessions: %s", sessionIds);
workaroundIspnDeadlock(manager, new Runnable() {
@Override
public void run() {
for (String sessionId : sessionIds) {
logoutSession(manager, sessionId);
}
}
});
}
protected void logoutSession(SessionManager manager, String httpSessionId) {
log.debugf("logoutHttpSession: %s", httpSessionId);
Session session = getSessionById(manager, httpSessionId);
try {
if (session != null) session.invalidate(null);
} catch (Exception e) {
log.warnf("Session %s not present or already invalidated.", httpSessionId);
}
}
protected Session getSessionById(SessionManager manager, final String sessionId) {
// TODO: Workaround for WFLY-3345. Remove this once we move to wildfly 8.2
if (manager.getClass().getName().equals("org.wildfly.clustering.web.undertow.session.DistributableSessionManager")) {
return manager.getSession(null, new SessionConfig() {
@Override
public void setSessionId(HttpServerExchange exchange, String sessionId) {
}
@Override
public void clearSession(HttpServerExchange exchange, String sessionId) {
}
@Override
public String findSessionId(HttpServerExchange exchange) {
return sessionId;
}
@Override
public SessionCookieSource sessionCookieSource(HttpServerExchange exchange) {
return null;
}
@Override
public String rewriteUrl(String originalUrl, String sessionId) {
return null;
}
});
} else {
return manager.getSession(sessionId);
}
}
@Override
public void sessionCreated(Session session, HttpServerExchange exchange) {
}
@Override
public void sessionDestroyed(Session session, HttpServerExchange exchange, SessionDestroyedReason reason) {
}
@Override
public void sessionIdChanged(Session session, String oldSessionId) {
}
@Override
public void attributeAdded(Session session, String name, Object value) {
}
@Override
public void attributeUpdated(Session session, String name, Object newValue, Object oldValue) {
}
@Override
public void attributeRemoved(Session session, String name, Object oldValue) {
}
}

View file

@ -997,11 +997,6 @@
<artifactId>keycloak-saml-as7-subsystem</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-wildfly-elytron-adapter</artifactId>