Remove the SAML undertow adapter

Closes #30554

Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
rmartinc 2024-06-19 13:23:45 +02:00 committed by Marek Posolda
parent 6b07b67667
commit f690947cea
30 changed files with 2 additions and 1530 deletions

View file

@ -34,7 +34,6 @@
<module>core-public</module>
<module>core</module>
<module>core-jakarta</module>
<module>undertow</module>
<module>wildfly</module>
<module>wildfly-elytron</module>
<module>wildfly-elytron-jakarta</module>

View file

@ -1,91 +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-saml-undertow-adapter</artifactId>
<name>Keycloak Undertow SAML Adapter</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</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,175 +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.saml.undertow;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.NotificationReceiver;
import io.undertow.security.api.SecurityContext;
import io.undertow.security.api.SecurityNotification;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.AttachmentKey;
import io.undertow.util.Headers;
import io.undertow.util.StatusCodes;
import org.keycloak.adapters.saml.SamlAuthenticator;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlDeploymentContext;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.undertow.UndertowHttpFacade;
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
/**
* Abstract base class for a Keycloak-enabled Undertow AuthenticationMechanism.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public abstract class AbstractSamlAuthMech implements AuthenticationMechanism {
private static final Logger LOG = Logger.getLogger(AbstractSamlAuthMech.class.getName());
public static final AttachmentKey<AuthChallenge> KEYCLOAK_CHALLENGE_ATTACHMENT_KEY = AttachmentKey.create(AuthChallenge.class);
protected SamlDeploymentContext deploymentContext;
protected UndertowUserSessionManagement sessionManagement;
protected String errorPage;
public AbstractSamlAuthMech(SamlDeploymentContext deploymentContext, UndertowUserSessionManagement sessionManagement, String errorPage) {
this.deploymentContext = deploymentContext;
this.sessionManagement = sessionManagement;
this.errorPage = errorPage;
}
@Override
public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) {
AuthChallenge challenge = exchange.getAttachment(KEYCLOAK_CHALLENGE_ATTACHMENT_KEY);
if (challenge != null) {
UndertowHttpFacade facade = createFacade(exchange);
if (challenge.challenge(facade)) {
return new ChallengeResult(true, exchange.getResponseCode());
}
}
return new ChallengeResult(false);
}
protected Integer servePage(final HttpServerExchange exchange, final String location) {
sendRedirect(exchange, location);
return StatusCodes.TEMPORARY_REDIRECT;
}
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
static void sendRedirect(final HttpServerExchange exchange, final String location) {
if (location == null) {
LOG.log(Level.WARNING, "Logout page not set.");
exchange.setStatusCode(StatusCodes.NOT_FOUND);
exchange.endExchange();
return;
}
if (PROTOCOL_PATTERN.matcher(location).find()) {
exchange.getResponseHeaders().put(Headers.LOCATION, location);
} else {
String loc = exchange.getRequestScheme() + "://" + exchange.getHostAndPort() + location;
exchange.getResponseHeaders().put(Headers.LOCATION, loc);
}
}
protected void registerNotifications(final SecurityContext securityContext) {
final NotificationReceiver logoutReceiver = new NotificationReceiver() {
@Override
public void handleNotification(SecurityNotification notification) {
if (notification.getEventType() != SecurityNotification.EventType.LOGGED_OUT)
return;
HttpServerExchange exchange = notification.getExchange();
UndertowHttpFacade facade = createFacade(exchange);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
SamlSessionStore sessionStore = getTokenStore(exchange, facade, deployment, securityContext);
sessionStore.logoutAccount();
}
};
securityContext.registerNotificationReceiver(logoutReceiver);
}
/**
* Call this inside your authenticate method.
*/
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
UndertowHttpFacade facade = createFacade(exchange);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
if (!deployment.isConfigured()) {
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
SamlSessionStore sessionStore = getTokenStore(exchange, facade, deployment, securityContext);
SamlAuthenticator authenticator = null;
if (exchange.getRequestPath().endsWith("/saml")) {
authenticator = new UndertowSamlEndpoint(facade, deploymentContext.resolveDeployment(facade), sessionStore);
} else {
authenticator = new UndertowSamlAuthenticator(securityContext, facade, deploymentContext.resolveDeployment(facade), sessionStore);
}
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
registerNotifications(securityContext);
return AuthenticationMechanismOutcome.AUTHENTICATED;
}
if (outcome == AuthOutcome.NOT_AUTHENTICATED) {
// we are in passive mode and user is not authenticated, let app server to try another auth mechanism
// See KEYCLOAK-2107, AbstractSamlAuthenticationHandler
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
if (outcome == AuthOutcome.LOGGED_OUT) {
securityContext.logout();
if (deployment.getLogoutPage() != null) {
redirectLogout(deployment, exchange);
}
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
exchange.putAttachment(KEYCLOAK_CHALLENGE_ATTACHMENT_KEY, challenge);
if (authenticator instanceof UndertowSamlEndpoint) {
exchange.getSecurityContext().setAuthenticationRequired();
}
}
if (outcome == AuthOutcome.FAILED) {
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
protected void redirectLogout(SamlDeployment deployment, HttpServerExchange exchange) {
String page = deployment.getLogoutPage();
sendRedirect(exchange, page);
exchange.setStatusCode(StatusCodes.FOUND);
exchange.endExchange();
}
protected UndertowHttpFacade createFacade(HttpServerExchange exchange) {
return new UndertowHttpFacade(exchange);
}
protected abstract SamlSessionStore getTokenStore(HttpServerExchange exchange, HttpFacade facade, SamlDeployment deployment, SecurityContext securityContext);
}

View file

@ -1,103 +0,0 @@
/*
* Copyright 2017 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.saml.undertow;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.spi.SessionIdMapper;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.Session;
import io.undertow.server.session.SessionListener;
import java.util.Objects;
/**
*
* @author hmlnarik
*/
public class IdMapperUpdaterSessionListener implements SessionListener {
private final SessionIdMapper idMapper;
public IdMapperUpdaterSessionListener(SessionIdMapper idMapper) {
this.idMapper = idMapper;
}
@Override
public void sessionCreated(Session session, HttpServerExchange exchange) {
Object value = session.getAttribute(SamlSession.class.getName());
map(session.getId(), value);
}
@Override
public void sessionDestroyed(Session session, HttpServerExchange exchange, SessionDestroyedReason reason) {
if (reason != SessionDestroyedReason.UNDEPLOY) {
unmap(session.getId(), session.getAttribute(SamlSession.class.getName()));
}
}
@Override
public void attributeAdded(Session session, String name, Object value) {
if (Objects.equals(name, SamlSession.class.getName())) {
map(session.getId(), value);
}
}
@Override
public void attributeUpdated(Session session, String name, Object newValue, Object oldValue) {
if (Objects.equals(name, SamlSession.class.getName())) {
unmap(session.getId(), oldValue);
map(session.getId(), newValue);
}
}
@Override
public void attributeRemoved(Session session, String name, Object oldValue) {
if (Objects.equals(name, SamlSession.class.getName())) {
unmap(session.getId(), oldValue);
}
}
@Override
public void sessionIdChanged(Session session, String oldSessionId) {
Object value = session.getAttribute(SamlSession.class.getName());
if (value != null) {
unmap(oldSessionId, value);
map(session.getId(), value);
}
}
private void map(String sessionId, Object value) {
if (! (value instanceof SamlSession) || sessionId == null) {
return;
}
SamlSession account = (SamlSession) value;
idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), sessionId);
}
private void unmap(String sessionId, Object value) {
if (! (value instanceof SamlSession) || sessionId == null) {
return;
}
SamlSession samlSession = (SamlSession) value;
if (samlSession.getSessionIndex() != null) {
idMapper.removeSession(sessionId);
}
}
}

View file

@ -1,223 +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.saml.undertow;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.AuthenticationMechanismFactory;
import io.undertow.security.idm.Account;
import io.undertow.security.idm.Credential;
import io.undertow.security.idm.IdentityManager;
import io.undertow.server.handlers.form.FormParserFactory;
import io.undertow.servlet.ServletExtension;
import io.undertow.servlet.api.AuthMethodConfig;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.LoginConfig;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.ServletSessionConfig;
import io.undertow.servlet.api.WebResourceCollection;
import org.jboss.logging.Logger;
import org.keycloak.adapters.saml.AdapterConstants;
import org.keycloak.adapters.saml.DefaultSamlDeployment;
import org.keycloak.adapters.saml.SamlConfigResolver;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlDeploymentContext;
import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
import org.keycloak.adapters.undertow.ChangeSessionId;
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
import org.keycloak.saml.common.exceptions.ParsingException;
import javax.servlet.ServletContext;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class SamlServletExtension implements ServletExtension {
protected static Logger log = Logger.getLogger(SamlServletExtension.class);
// todo when this DeploymentInfo method of the same name is fixed.
public boolean isAuthenticationMechanismPresent(DeploymentInfo deploymentInfo, final String mechanismName) {
LoginConfig loginConfig = deploymentInfo.getLoginConfig();
if (loginConfig != null) {
for (AuthMethodConfig method : loginConfig.getAuthMethods()) {
if (method.getName().equalsIgnoreCase(mechanismName)) {
return true;
}
}
}
return false;
}
private static InputStream getXMLFromServletContext(ServletContext servletContext) {
String json = servletContext.getInitParameter(AdapterConstants.AUTH_DATA_PARAM_NAME);
if (json == null) {
return null;
}
return new ByteArrayInputStream(json.getBytes());
}
private static InputStream getConfigInputStream(ServletContext context) {
InputStream is = getXMLFromServletContext(context);
if (is == null) {
String path = context.getInitParameter("keycloak.config.file");
if (path == null) {
log.debug("using /WEB-INF/keycloak-saml.xml");
is = context.getResourceAsStream("/WEB-INF/keycloak-saml.xml");
} else {
try {
is = new FileInputStream(path);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
return is;
}
@Override
@SuppressWarnings("UseSpecificCatch")
public void handleDeployment(DeploymentInfo deploymentInfo, final ServletContext servletContext) {
if (!isAuthenticationMechanismPresent(deploymentInfo, "KEYCLOAK-SAML")) {
log.debug("auth-method is not keycloak saml!");
return;
}
log.debug("SamlServletException initialization");
// Possible scenarios:
// 1) The deployment has a keycloak.config.resolver specified and it exists:
// Outcome: adapter uses the resolver
// 2) The deployment has a keycloak.config.resolver and isn't valid (doesn't exist, isn't a resolver, ...) :
// Outcome: adapter is left unconfigured
// 3) The deployment doesn't have a keycloak.config.resolver , but has a keycloak.json (or equivalent)
// Outcome: adapter uses it
// 4) The deployment doesn't have a keycloak.config.resolver nor keycloak.json (or equivalent)
// Outcome: adapter is left unconfigured
SamlConfigResolver configResolver;
String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver");
SamlDeploymentContext deploymentContext = null;
if (configResolverClass != null) {
try {
configResolver = (SamlConfigResolver) deploymentInfo.getClassLoader().loadClass(configResolverClass).newInstance();
deploymentContext = new SamlDeploymentContext(configResolver);
log.infov("Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
} catch (Exception ex) {
log.warn("The specified resolver " + configResolverClass + " could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: " + ex.getMessage());
deploymentContext = new SamlDeploymentContext(new DefaultSamlDeployment());
}
} else {
InputStream is = getConfigInputStream(servletContext);
final SamlDeployment deployment;
if (is == null) {
log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
deployment = new DefaultSamlDeployment();
} else {
try {
ResourceLoader loader = new ResourceLoader() {
@Override
public InputStream getResourceAsStream(String resource) {
return servletContext.getResourceAsStream(resource);
}
};
deployment = new DeploymentBuilder().build(is, loader);
} catch (ParsingException e) {
throw new RuntimeException(e);
}
}
deploymentContext = new SamlDeploymentContext(deployment);
log.debug("Keycloak is using a per-deployment configuration.");
}
servletContext.setAttribute(SamlDeploymentContext.class.getName(), deploymentContext);
UndertowUserSessionManagement userSessionManagement = new UndertowUserSessionManagement();
final ServletSamlAuthMech mech = createAuthMech(deploymentInfo, deploymentContext, userSessionManagement);
mech.addTokenStoreUpdaters(deploymentInfo);
// setup handlers
deploymentInfo.addAuthenticationMechanism("KEYCLOAK-SAML", new AuthenticationMechanismFactory() {
@Override
public AuthenticationMechanism create(String s, FormParserFactory formParserFactory, Map<String, String> stringStringMap) {
return mech;
}
}); // authentication
deploymentInfo.setIdentityManager(new IdentityManager() {
@Override
public Account verify(Account account) {
return account;
}
@Override
public Account verify(String id, Credential credential) {
throw new IllegalStateException("Should never be called in Keycloak flow");
}
@Override
public Account verify(Credential credential) {
throw new IllegalStateException("Should never be called in Keycloak flow");
}
});
ServletSessionConfig cookieConfig = deploymentInfo.getServletSessionConfig();
if (cookieConfig == null) {
cookieConfig = new ServletSessionConfig();
}
if (cookieConfig.getPath() == null) {
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
cookieConfig.setPath(deploymentInfo.getContextPath());
deploymentInfo.setServletSessionConfig(cookieConfig);
}
addEndpointConstraint(deploymentInfo);
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
}
/**
* add security constraint to /saml so that the endpoint can be called and auth mechanism pinged.
* @param deploymentInfo
*/
protected void addEndpointConstraint(DeploymentInfo deploymentInfo) {
SecurityConstraint constraint = new SecurityConstraint();
WebResourceCollection collection = new WebResourceCollection();
collection.addUrlPattern("/saml");
constraint.addWebResourceCollection(collection);
deploymentInfo.addSecurityConstraint(constraint);
}
protected ServletSamlAuthMech createAuthMech(DeploymentInfo deploymentInfo, SamlDeploymentContext deploymentContext, UndertowUserSessionManagement userSessionManagement) {
return new ServletSamlAuthMech(deploymentContext, userSessionManagement, getErrorPage(deploymentInfo));
}
protected String getErrorPage(DeploymentInfo deploymentInfo) {
LoginConfig loginConfig = deploymentInfo.getLoginConfig();
String errorPage = null;
if (loginConfig != null) {
errorPage = loginConfig.getErrorPage();
}
return errorPage;
}
}

View file

@ -1,152 +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.saml.undertow;
import io.undertow.security.api.SecurityContext;
import io.undertow.server.HttpServerExchange;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.util.Headers;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlDeploymentContext;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.spi.*;
import org.keycloak.adapters.undertow.ServletHttpFacade;
import org.keycloak.adapters.undertow.UndertowHttpFacade;
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
import io.undertow.servlet.api.DeploymentInfo;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Map;
import org.jboss.logging.Logger;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ServletSamlAuthMech extends AbstractSamlAuthMech {
private static final Logger LOG = Logger.getLogger(ServletSamlAuthMech.class);
protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
protected SessionIdMapperUpdater idMapperUpdater = SessionIdMapperUpdater.DIRECT;
public ServletSamlAuthMech(SamlDeploymentContext deploymentContext, UndertowUserSessionManagement sessionManagement, String errorPage) {
super(deploymentContext, sessionManagement, errorPage);
}
public void addTokenStoreUpdaters(DeploymentInfo deploymentInfo) {
deploymentInfo.addSessionListener(new IdMapperUpdaterSessionListener(idMapper)); // This takes care of HTTP sessions manipulated locally
SessionIdMapperUpdater updater = SessionIdMapperUpdater.EXTERNAL;
try {
Map<String, String> initParameters = deploymentInfo.getInitParameters();
String idMapperSessionUpdaterClasses = initParameters == null
? null
: initParameters.get("keycloak.sessionIdMapperUpdater.classes");
if (idMapperSessionUpdaterClasses == null) {
return;
}
for (String clazz : idMapperSessionUpdaterClasses.split("\\s*,\\s*")) {
if (! clazz.isEmpty()) {
updater = invokeAddTokenStoreUpdaterMethod(clazz, deploymentInfo, updater);
}
}
} finally {
setIdMapperUpdater(updater);
}
}
private SessionIdMapperUpdater invokeAddTokenStoreUpdaterMethod(String idMapperSessionUpdaterClass, DeploymentInfo deploymentInfo,
SessionIdMapperUpdater previousIdMapperUpdater) {
try {
Class<?> clazz = deploymentInfo.getClassLoader().loadClass(idMapperSessionUpdaterClass);
Method addTokenStoreUpdatersMethod = clazz.getMethod("addTokenStoreUpdaters", DeploymentInfo.class, SessionIdMapper.class, SessionIdMapperUpdater.class);
if (! Modifier.isStatic(addTokenStoreUpdatersMethod.getModifiers())
|| ! Modifier.isPublic(addTokenStoreUpdatersMethod.getModifiers())
|| ! SessionIdMapperUpdater.class.isAssignableFrom(addTokenStoreUpdatersMethod.getReturnType())) {
LOG.errorv("addTokenStoreUpdaters method in class {0} has to be public static. Ignoring class.", idMapperSessionUpdaterClass);
return previousIdMapperUpdater;
}
LOG.debugv("Initializing sessionIdMapperUpdater class {0}", idMapperSessionUpdaterClass);
return (SessionIdMapperUpdater) addTokenStoreUpdatersMethod.invoke(null, deploymentInfo, idMapper, previousIdMapperUpdater);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) {
LOG.warnv(ex, "Cannot use sessionIdMapperUpdater class {0}", idMapperSessionUpdaterClass);
return previousIdMapperUpdater;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
LOG.warnv(ex, "Cannot use {0}.addTokenStoreUpdaters(DeploymentInfo, SessionIdMapper) method", idMapperSessionUpdaterClass);
return previousIdMapperUpdater;
}
}
@Override
protected SamlSessionStore getTokenStore(HttpServerExchange exchange, HttpFacade facade, SamlDeployment deployment, SecurityContext securityContext) {
return new ServletSamlSessionStore(exchange, sessionManagement, securityContext, idMapper, idMapperUpdater, deployment);
}
@Override
protected UndertowHttpFacade createFacade(HttpServerExchange exchange) {
return new ServletHttpFacade(exchange);
}
@Override
protected void redirectLogout(SamlDeployment deployment, HttpServerExchange exchange) {
exchange.getResponseHeaders().add(Headers.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
exchange.getResponseHeaders().add(Headers.PRAGMA, "no-cache");
exchange.getResponseHeaders().add(Headers.EXPIRES, "0");
super.redirectLogout(deployment, exchange);
}
@Override
protected Integer servePage(HttpServerExchange exchange, String location) {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
ServletRequest req = servletRequestContext.getServletRequest();
ServletResponse resp = servletRequestContext.getServletResponse();
RequestDispatcher disp = req.getRequestDispatcher(location);
//make sure the login page is never cached
exchange.getResponseHeaders().add(Headers.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
exchange.getResponseHeaders().add(Headers.PRAGMA, "no-cache");
exchange.getResponseHeaders().add(Headers.EXPIRES, "0");
try {
disp.forward(req, resp);
} catch (ServletException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
public SessionIdMapperUpdater getIdMapperUpdater() {
return idMapperUpdater;
}
protected void setIdMapperUpdater(SessionIdMapperUpdater idMapperUpdater) {
this.idMapperUpdater = idMapperUpdater;
}
}

View file

@ -1,263 +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.saml.undertow;
import io.undertow.security.api.SecurityContext;
import io.undertow.security.idm.Account;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.SessionManager;
import io.undertow.servlet.handlers.ServletRequestContext;
import io.undertow.servlet.spec.HttpSessionImpl;
import org.jboss.logging.Logger;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.SamlUtil;
import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.spi.SessionIdMapperUpdater;
import org.keycloak.adapters.undertow.ChangeSessionId;
import org.keycloak.adapters.undertow.SavedRequest;
import org.keycloak.adapters.undertow.ServletHttpFacade;
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar;
import java.security.Principal;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Session store manipulation methods per single HTTP exchange.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ServletSamlSessionStore implements SamlSessionStore {
protected static Logger log = Logger.getLogger(SamlSessionStore.class);
public static final String SAML_REDIRECT_URI = "SAML_REDIRECT_URI";
private final HttpServerExchange exchange;
private final UndertowUserSessionManagement sessionManagement;
private final SecurityContext securityContext;
private final SessionIdMapper idMapper;
private final SessionIdMapperUpdater idMapperUpdater;
protected final SamlDeployment deployment;
public ServletSamlSessionStore(HttpServerExchange exchange, UndertowUserSessionManagement sessionManagement,
SecurityContext securityContext,
SessionIdMapper idMapper, SessionIdMapperUpdater idMapperUpdater,
SamlDeployment deployment) {
this.exchange = exchange;
this.sessionManagement = sessionManagement;
this.securityContext = securityContext;
this.idMapper = idMapper;
this.deployment = deployment;
this.idMapperUpdater = idMapperUpdater;
}
@Override
public void setCurrentAction(CurrentAction action) {
if (action == CurrentAction.NONE && getRequest().getSession(false) == null) return;
getRequest().getSession().setAttribute(CURRENT_ACTION, action);
}
@Override
public boolean isLoggingIn() {
HttpSession session = getRequest().getSession(false);
if (session == null) return false;
CurrentAction action = (CurrentAction)session.getAttribute(CURRENT_ACTION);
return action == CurrentAction.LOGGING_IN;
}
@Override
public boolean isLoggingOut() {
HttpSession session = getRequest().getSession(false);
if (session == null) return false;
CurrentAction action = (CurrentAction)session.getAttribute(CURRENT_ACTION);
return action == CurrentAction.LOGGING_OUT;
}
@Override
public void logoutAccount() {
HttpSession session = getSession(false);
if (session != null) {
SamlSession samlSession = (SamlSession)session.getAttribute(SamlSession.class.getName());
if (samlSession != null) {
if (samlSession.getSessionIndex() != null) {
idMapperUpdater.removeSession(idMapper, session.getId());
}
session.removeAttribute(SamlSession.class.getName());
}
session.removeAttribute(SAML_REDIRECT_URI);
}
}
@Override
public void logoutByPrincipal(String principal) {
Set<String> sessions = idMapper.getUserSessions(principal);
if (sessions != null) {
List<String> ids = new LinkedList<>();
ids.addAll(sessions);
logoutSessionIds(ids);
for (String id : ids) {
idMapperUpdater.removeSession(idMapper, id);
}
}
}
@Override
public void logoutBySsoId(List<String> ssoIds) {
if (ssoIds == null) return;
List<String> sessionIds = new LinkedList<>();
for (String id : ssoIds) {
String sessionId = idMapper.getSessionFromSSO(id);
if (sessionId != null) {
sessionIds.add(sessionId);
idMapperUpdater.removeSession(idMapper, sessionId);
}
}
logoutSessionIds(sessionIds);
}
protected void logoutSessionIds(List<String> sessionIds) {
if (sessionIds == null || sessionIds.isEmpty()) return;
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
SessionManager sessionManager = servletRequestContext.getDeployment().getSessionManager();
sessionManagement.logoutHttpSessions(sessionManager, sessionIds);
}
@Override
public boolean isLoggedIn() {
HttpSession session = getSession(false);
if (session == null) {
log.debug("Session was not found");
return false;
}
if (! idMapper.hasSession(session.getId()) && ! idMapperUpdater.refreshMapping(idMapper, session.getId())) {
log.debugf("Session %s has expired on some other node", session.getId());
session.removeAttribute(SamlSession.class.getName());
return false;
}
final SamlSession samlSession = SamlUtil.validateSamlSession(session.getAttribute(SamlSession.class.getName()), deployment);
if (samlSession == null) {
return false;
}
Account undertowAccount = new Account() {
@Override
public Principal getPrincipal() {
return samlSession.getPrincipal();
}
@Override
public Set<String> getRoles() {
return samlSession.getRoles();
}
};
securityContext.authenticationComplete(undertowAccount, "KEYCLOAK-SAML", false);
restoreRequest();
return true;
}
@Override
public void saveAccount(SamlSession account) {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpSession session = getSession(true);
session.setAttribute(SamlSession.class.getName(), account);
sessionManagement.login(servletRequestContext.getDeployment().getSessionManager());
String sessionId = changeSessionId(session);
idMapperUpdater.map(idMapper, account.getSessionIndex(), account.getPrincipal().getSamlSubject(), sessionId);
}
protected String changeSessionId(HttpSession session) {
if (!deployment.turnOffChangeSessionIdOnLogin()) return ChangeSessionId.changeSessionId(exchange, false);
else return session.getId();
}
@Override
public SamlSession getAccount() {
HttpSession session = getSession(true);
return (SamlSession)session.getAttribute(SamlSession.class.getName());
}
@Override
public String getRedirectUri() {
final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
String redirect = (String)session.getAttribute(SAML_REDIRECT_URI);
if (redirect == null) {
ServletHttpFacade facade = new ServletHttpFacade(exchange);
HttpServletRequest req = (HttpServletRequest)sc.getServletRequest();
String contextPath = req.getContextPath();
String baseUri = KeycloakUriBuilder.fromUri(req.getRequestURL().toString()).replacePath(contextPath).build().toString();
return SamlUtil.getRedirectTo(facade, contextPath, baseUri);
}
return redirect;
}
@Override
public void saveRequest() {
SavedRequest.trySaveRequest(exchange);
final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(exchange.getRequestURI())
.replaceQuery(exchange.getQueryString());
if (!exchange.isHostIncludedInRequestURI()) uriBuilder.scheme(exchange.getRequestScheme()).host(exchange.getHostAndPort());
String uri = uriBuilder.buildAsString();
session.setAttribute(SAML_REDIRECT_URI, uri);
}
@Override
public boolean restoreRequest() {
HttpSession session = getSession(false);
if (session == null) return false;
SavedRequest.tryRestoreRequest(exchange, session);
session.removeAttribute(SAML_REDIRECT_URI);
return false;
}
protected HttpSession getSession(boolean create) {
HttpServletRequest req = getRequest();
return req.getSession(create);
}
private HttpServletResponse getResponse() {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
return (HttpServletResponse)servletRequestContext.getServletResponse();
}
private HttpServletRequest getRequest() {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
return (HttpServletRequest) servletRequestContext.getServletRequest();
}
}

View file

@ -1,67 +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.saml.undertow;
import io.undertow.security.api.SecurityContext;
import io.undertow.security.idm.Account;
import org.keycloak.adapters.saml.SamlAuthenticator;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.profile.SamlAuthenticationHandler;
import org.keycloak.adapters.saml.profile.webbrowsersso.BrowserHandler;
import org.keycloak.adapters.spi.HttpFacade;
import java.security.Principal;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UndertowSamlAuthenticator extends SamlAuthenticator {
protected SecurityContext securityContext;
public UndertowSamlAuthenticator(SecurityContext securityContext, HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
super(facade, deployment, sessionStore);
this.securityContext = securityContext;
}
@Override
protected void completeAuthentication(final SamlSession samlSession) {
Account undertowAccount = new Account() {
@Override
public Principal getPrincipal() {
return samlSession.getPrincipal();
}
@Override
public Set<String> getRoles() {
return samlSession.getRoles();
}
};
securityContext.authenticationComplete(undertowAccount, "KEYCLOAK-SAML", false);
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new BrowserHandler(facade, deployment, sessionStore);
}
}

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.saml.undertow;
import org.keycloak.adapters.saml.SamlAuthenticator;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.saml.profile.SamlAuthenticationHandler;
import org.keycloak.adapters.saml.profile.webbrowsersso.SamlEndpoint;
import org.keycloak.adapters.spi.HttpFacade;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UndertowSamlEndpoint extends SamlAuthenticator {
public UndertowSamlEndpoint(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
super(facade, deployment, sessionStore);
}
@Override
protected void completeAuthentication(SamlSession samlSession) {
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new SamlEndpoint(facade, deployment, sessionStore);
}
}

View file

@ -1,18 +0,0 @@
#
# Copyright 2018 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.
#
org.keycloak.adapters.saml.undertow.SamlServletExtension

View file

@ -92,16 +92,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Authorization -->
<dependency>

View file

@ -22,7 +22,6 @@
<module xmlns="urn:jboss:module:1.3" name="org.keycloak.keycloak-adapter-spi">
<resources>
<artifact name="${org.keycloak:keycloak-adapter-spi}"/>
<artifact name="${org.keycloak:keycloak-undertow-adapter-spi}"/>
</resources>
<dependencies>
<module name="javax.api"/>

View file

@ -134,17 +134,6 @@
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-undertow-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-wildfly-elytron-jakarta-adapter</artifactId>
@ -167,17 +156,6 @@
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${ee.maven.groupId}</groupId>
<artifactId>wildfly-ee-galleon-pack</artifactId>
@ -296,4 +274,4 @@
</build>
</profile>
</profiles>
</project>
</project>

View file

@ -11,16 +11,6 @@
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>https://raw.githubusercontent.com/keycloak/keycloak/999-SNAPSHOT/LICENSE.txt</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
@ -101,16 +91,6 @@
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-undertow-adapter</artifactId>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>https://raw.githubusercontent.com/keycloak/keycloak/999-SNAPSHOT/LICENSE.txt</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-wildfly-elytron-jakarta-adapter</artifactId>

View file

@ -22,7 +22,6 @@
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-adapter-spi">
<resources>
<artifact name="${org.keycloak:keycloak-adapter-spi}"/>
<artifact name="${org.keycloak:keycloak-undertow-adapter-spi}"/>
</resources>
<dependencies>
<module name="javax.api"/>

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-saml-undertow-adapter">
<properties>
<property name="jboss.api" value="private"/>
</properties>
<resources>
<artifact name="${org.keycloak:keycloak-saml-undertow-adapter}"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.bouncycastle" />
<module name="jakarta.servlet.api"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.xnio"/>
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>
<module name="org.keycloak.keycloak-saml-adapter-api-public"/>
<module name="org.keycloak.keycloak-saml-adapter-core-jakarta"/>
<module name="org.keycloak.keycloak-common"/>
<module name="org.apache.httpcomponents"/>
</dependencies>
</module>

View file

@ -33,7 +33,6 @@
<module name="org.jboss.logging"/>
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.keycloak.keycloak-saml-undertow-adapter"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>

View file

@ -49,7 +49,6 @@
<module-def name="org.keycloak.keycloak-adapter-spi">
<maven-resource group="org.keycloak" artifact="keycloak-adapter-spi"/>
<maven-resource group="org.keycloak" artifact="keycloak-undertow-adapter-spi"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-core">
@ -72,10 +71,6 @@
<maven-resource group="org.keycloak" artifact="keycloak-jboss-adapter-core"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-undertow-adapter">
<maven-resource group="org.keycloak" artifact="keycloak-saml-undertow-adapter"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-wildfly-jakarta-subsystem">
<maven-resource group="org.keycloak" artifact="keycloak-saml-wildfly-jakarta-subsystem"/>
</module-def>

View file

@ -74,16 +74,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
@ -124,16 +114,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-undertow-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-saml-undertow-adapter">
<properties>
<property name="jboss.api" value="private"/>
</properties>
<resources>
<!-- Insert resources here -->
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.bouncycastle" />
<module name="jakarta.servlet.api"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.xnio"/>
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>
<module name="org.keycloak.keycloak-saml-adapter-api-public"/>
<module name="org.keycloak.keycloak-saml-adapter-core-jakarta"/>
<module name="org.keycloak.keycloak-common"/>
<module name="org.apache.httpcomponents"/>
</dependencies>
</module>

View file

@ -33,7 +33,6 @@
<module name="org.jboss.logging"/>
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.keycloak.keycloak-saml-undertow-adapter"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>

View file

@ -49,7 +49,6 @@
<module-def name="org.keycloak.keycloak-adapter-spi">
<maven-resource group="org.keycloak" artifact="keycloak-adapter-spi"/>
<maven-resource group="org.keycloak" artifact="keycloak-undertow-adapter-spi"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-core">
@ -72,10 +71,6 @@
<maven-resource group="org.keycloak" artifact="keycloak-jboss-adapter-core"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-undertow-adapter">
<maven-resource group="org.keycloak" artifact="keycloak-saml-undertow-adapter"/>
</module-def>
<module-def name="org.keycloak.keycloak-saml-wildfly-subsystem">
<maven-resource group="org.keycloak" artifact="keycloak-saml-wildfly-subsystem"/>
</module-def>

View file

@ -74,16 +74,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-undertow-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
@ -124,16 +114,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-undertow-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-saml-undertow-adapter">
<properties>
<property name="jboss.api" value="private"/>
</properties>
<resources>
<!-- Insert resources here -->
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.bouncycastle" />
<module name="javax.servlet.api"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.xnio"/>
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>
<module name="org.keycloak.keycloak-saml-adapter-api-public"/>
<module name="org.keycloak.keycloak-saml-adapter-core"/>
<module name="org.keycloak.keycloak-common"/>
<module name="org.apache.httpcomponents"/>
</dependencies>
</module>

View file

@ -34,7 +34,6 @@
<module name="io.undertow.core"/>
<module name="io.undertow.servlet"/>
<module name="org.picketbox"/>
<module name="org.keycloak.keycloak-saml-undertow-adapter"/>
<module name="org.keycloak.keycloak-adapter-spi"/>
<module name="org.keycloak.keycloak-saml-core-public"/>
<module name="org.keycloak.keycloak-saml-core"/>

View file

@ -1133,11 +1133,6 @@
<artifactId>keycloak-saml-wildfly-jakarta-subsystem</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-undertow-adapter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>

View file

@ -15,7 +15,6 @@
<modules>
<module>undertow-adapter-spi-jakarta</module>
<module>undertow-adapter-saml-jakarta</module>
</modules>
<properties>
@ -34,4 +33,4 @@
</properties>
</profile>
</profiles>
</project>
</project>

View file

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>integration-arquillian-servers-adapter-spi</artifactId>
<groupId>org.keycloak.testsuite</groupId>
<version>999.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-saml-undertow-adapter-jakarta</artifactId>
<name>Undertow SAML Adapter (JakartaEE)</name>
<packaging>jar</packaging>
<properties>
<jakarta-transformer-sources>${project.basedir}/../../../../../adapters/saml/undertow</jakarta-transformer-sources>
<jakarta-transformer-target>${project.basedir}</jakarta-transformer-target>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>keycloak-undertow-adapter-spi-jakarta</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</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>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>transform</id>
<phase>initialize</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="plugin_classpath" refid="maven.plugin.classpath" />
<java classname="org.eclipse.transformer.cli.JakartaTransformerCLI" fork="true">
<arg value="-o" />
<arg value="${jakarta-transformer-sources}" />
<arg value="${jakarta-transformer-target}/tmp" />
<classpath>
<pathelement path="${plugin_classpath}" />
</classpath>
</java>
<touch>
<fileset dir="${jakarta-transformer-target}"/>
</touch>
<copy todir="${jakarta-transformer-target}" overwrite="false">
<fileset dir="${jakarta-transformer-target}/tmp"/>
</copy>
<delete dir="${jakarta-transformer-target}/tmp"/>
</target>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.transformer</groupId>
<artifactId>org.eclipse.transformer.cli</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.14</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View file

@ -181,11 +181,6 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>keycloak-saml-undertow-adapter-jakarta</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Dependency on services from integration-arquillian -->
<dependency>
<groupId>org.keycloak.testsuite</groupId>