Remove the SAML undertow adapter
Closes #30554 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
6b07b67667
commit
f690947cea
30 changed files with 2 additions and 1530 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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"/>
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
src/
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue