KEYCLOAK-7094 Support redirect to external logout page for elytron adapter

This commit is contained in:
vramik 2018-06-13 11:43:05 +02:00 committed by Hynek Mlnařík
parent dd93de75d9
commit 5f1f3dff5e
2 changed files with 50 additions and 10 deletions

View file

@ -19,6 +19,7 @@ package org.keycloak.adapters.saml.elytron;
import java.net.URI;
import java.util.Map;
import java.util.regex.Pattern;
import javax.security.auth.callback.CallbackHandler;
@ -142,14 +143,23 @@ class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticat
exchange.getResponse().setStatus(302);
}
private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+.-]*:");
static void sendRedirect(final ElytronHttpFacade exchange, final String location) {
// TODO - String concatenation to construct URLS is extremely error prone - switch to a URI which will better
// handle this.
URI uri = exchange.getURI();
String path = uri.getPath();
String relativePath = exchange.getRequest().getRelativePath();
String contextPath = path.substring(0, path.indexOf(relativePath));
String loc = exchange.getURI().getScheme() + "://" + exchange.getURI().getHost() + ":" + exchange.getURI().getPort() + contextPath + location;
exchange.getResponse().setHeader("Location", loc);
if (location == null) {
LOGGER.warn("Logout page not set.");
exchange.getResponse().setStatus(302);
return;
}
if (PROTOCOL_PATTERN.matcher(location).find()) {
exchange.getResponse().setHeader("Location", location);
} else {
URI uri = exchange.getURI();
String path = uri.getPath();
String relativePath = exchange.getRequest().getRelativePath();
String contextPath = path.substring(0, path.indexOf(relativePath));
String loc = exchange.getURI().getScheme() + "://" + exchange.getURI().getHost() + ":" + exchange.getURI().getPort() + contextPath + location;
exchange.getResponse().setHeader("Location", loc);
}
}
}

View file

@ -103,6 +103,22 @@ public class IOUtil {
}
}
/**
* Modifies attribute value according to the given regex (first occurrence) iff
* there are following conditions accomplished:
*
* - exactly one node is found within the document
* - the attribute of the node exists
* - the regex is found in the value of the attribute
*
* Otherwise there is nothing changed.
*
* @param doc
* @param tagName
* @param attributeName
* @param regex
* @param replacement
*/
public static void modifyDocElementAttribute(Document doc, String tagName, String attributeName, String regex, String replacement) {
NodeList nodes = doc.getElementsByTagName(tagName);
if (nodes.getLength() != 1) {
@ -115,7 +131,7 @@ public class IOUtil {
log.warn("Not able to find attribute " + attributeName + " within element: " + tagName);
return;
}
node.setTextContent(node.getTextContent().replace(regex, replacement));
node.setTextContent(node.getTextContent().replaceFirst(regex, replacement));
}
public static void removeNodeByAttributeValue(Document doc, String parentTag, String tagName, String attributeName, String value){
@ -141,6 +157,20 @@ public class IOUtil {
}
}
/**
* Modifies element text value according to the given regex (first occurrence) iff
* there are following conditions accomplished:
*
* - exactly one node is found within the document
* - the regex is found in the text content of the element
*
* Otherwise there is nothing changed.
*
* @param doc
* @param tagName
* @param regex
* @param replacement
*/
public static void modifyDocElementValue(Document doc, String tagName, String regex, String replacement) {
NodeList nodes = doc.getElementsByTagName(tagName);
if (nodes.getLength() != 1) {
@ -154,7 +184,7 @@ public class IOUtil {
return;
}
node.setTextContent(node.getTextContent().replace(regex, replacement));
node.setTextContent(node.getTextContent().replaceFirst(regex, replacement));
}
public static void setDocElementAttributeValue(Document doc, String tagName, String attributeName, String value) {