KEYCLOAK_SECURITY_CONTEXT_KEY = AttachmentKey.create(KeycloakSecurityContext.class);
+
+ public OIDCServletUndertowHttpFacade(HttpServerExchange exchange) {
+ super(exchange);
+ }
+
+ @Override
+ public KeycloakSecurityContext getSecurityContext() {
+ return exchange.getAttachment(KEYCLOAK_SECURITY_CONTEXT_KEY);
+ }
+
+}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
index b5984a491f..b546e76e50 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
@@ -79,7 +79,7 @@ public class ServletKeycloakAuthMech extends AbstractUndertowKeycloakAuthMech {
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
- UndertowHttpFacade facade = new OIDCUndertowHttpFacade(exchange);
+ UndertowHttpFacade facade = createFacade(exchange);
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
if (!deployment.isConfigured()) {
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
@@ -119,4 +119,8 @@ public class ServletKeycloakAuthMech extends AbstractUndertowKeycloakAuthMech {
}
}
+ @Override
+ public UndertowHttpFacade createFacade(HttpServerExchange exchange) {
+ return new OIDCServletUndertowHttpFacade(exchange);
+ }
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletPreAuthActionsHandler.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletPreAuthActionsHandler.java
index 362cdb06e2..05672db630 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletPreAuthActionsHandler.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletPreAuthActionsHandler.java
@@ -61,11 +61,13 @@ public class ServletPreAuthActionsHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
- UndertowHttpFacade facade = new OIDCUndertowHttpFacade(exchange);
+ UndertowHttpFacade facade = new OIDCServletUndertowHttpFacade(exchange);
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
SessionManagementBridge bridge = new SessionManagementBridge(userSessionManagement, servletRequestContext.getDeployment().getSessionManager());
PreAuthActionsHandler handler = new PreAuthActionsHandler(bridge, deploymentContext, facade);
if (handler.handleRequest()) return;
next.handleRequest(exchange);
}
+
+
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowAuthenticationMechanism.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowAuthenticationMechanism.java
index 85b75813e1..88ba70545f 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowAuthenticationMechanism.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowAuthenticationMechanism.java
@@ -25,7 +25,7 @@ public class UndertowAuthenticationMechanism extends AbstractUndertowKeycloakAut
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
- UndertowHttpFacade facade = new OIDCUndertowHttpFacade(exchange);
+ UndertowHttpFacade facade = createFacade(exchange);
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
if (!deployment.isConfigured()) {
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowPreAuthActionsHandler.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowPreAuthActionsHandler.java
index 77194e1dc0..8ad97efd75 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowPreAuthActionsHandler.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowPreAuthActionsHandler.java
@@ -47,10 +47,14 @@ public class UndertowPreAuthActionsHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
- UndertowHttpFacade facade = new OIDCUndertowHttpFacade(exchange);
+ UndertowHttpFacade facade = createFacade(exchange);
SessionManagementBridge bridge = new SessionManagementBridge(userSessionManagement, sessionManager);
PreAuthActionsHandler handler = new PreAuthActionsHandler(bridge, deploymentContext, facade);
if (handler.handleRequest()) return;
next.handleRequest(exchange);
}
+
+ public UndertowHttpFacade createFacade(HttpServerExchange exchange) {
+ return new OIDCUndertowHttpFacade(exchange);
+ }
}
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
index a34fb1b847..158bae89b9 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
@@ -26,11 +26,6 @@ public class InitiateLogin implements AuthChallenge {
this.sessionStore = sessionStore;
}
- @Override
- public boolean errorPage() {
- return false;
- }
-
@Override
public int getResponseCode() {
return 0;
@@ -87,6 +82,7 @@ public class InitiateLogin implements AuthChallenge {
Document document = authnRequestBuilder.toDocument();
SamlDeployment.Binding samlBinding = deployment.getIDP().getSingleSignOnService().getRequestBinding();
SamlUtil.sendSaml(true, httpFacade, actionUrl, binding, document, samlBinding);
+ sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.LOGGING_IN);
} catch (Exception e) {
throw new RuntimeException("Could not create authentication request.", e);
}
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java
new file mode 100755
index 0000000000..8b631031cb
--- /dev/null
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticationError.java
@@ -0,0 +1,43 @@
+package org.keycloak.adapters.saml;
+
+import org.keycloak.adapters.spi.AuthenticationError;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
+
+/**
+ * Object that describes the SAML error that happened.
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAuthenticationError implements AuthenticationError {
+ public static enum Reason {
+ EXTRACTION_FAILURE,
+ INVALID_SIGNATURE,
+ ERROR_STATUS
+ }
+
+ private Reason reason;
+
+ private StatusResponseType status;
+
+ public SamlAuthenticationError(Reason reason) {
+ this.reason = reason;
+ }
+
+ public SamlAuthenticationError(Reason reason, StatusResponseType status) {
+ this.reason = reason;
+ this.status = status;
+ }
+
+ public SamlAuthenticationError(StatusResponseType statusType) {
+ this.status = statusType;
+ }
+
+ public Reason getReason() {
+ return reason;
+ }
+ public StatusResponseType getStatus() {
+ return status;
+ }
+}
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
index 39f026ac2b..1d289d764e 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
@@ -1,10 +1,12 @@
package org.keycloak.adapters.saml;
import org.jboss.logging.Logger;
-import org.keycloak.common.VerificationException;
import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade;
+import org.keycloak.common.VerificationException;
+import org.keycloak.common.util.KeycloakUriBuilder;
+import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.dom.saml.v2.assertion.AssertionType;
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
import org.keycloak.dom.saml.v2.assertion.AttributeType;
@@ -29,8 +31,6 @@ import org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature;
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
import org.keycloak.saml.processing.web.util.PostBindingUtil;
-import org.keycloak.common.util.KeycloakUriBuilder;
-import org.keycloak.common.util.MultivaluedHashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -74,7 +74,7 @@ public abstract class SamlAuthenticator {
return handleSamlRequest(samlRequest, relayState);
} else if (samlResponse != null) {
return handleSamlResponse(samlResponse, relayState);
- } else if (sessionStore.isLoggedIn()) {
+ } else if (sessionStore.isLoggedIn()) {
if (globalLogout) {
return globalLogout();
}
@@ -106,6 +106,7 @@ public abstract class SamlAuthenticator {
try {
SamlUtil.sendSaml(true, facade, deployment.getIDP().getSingleLogoutService().getRequestBindingUrl(), binding, logoutBuilder.buildDocument(), deployment.getIDP().getSingleLogoutService().getRequestBinding());
+ sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.LOGGING_OUT);
} catch (Exception e) {
log.error("Could not send global logout SAML request", e);
return AuthOutcome.FAILED;
@@ -155,7 +156,7 @@ public abstract class SamlAuthenticator {
protected AuthOutcome logoutRequest(LogoutRequestType request, String relayState) {
if (request.getSessionIndex() == null || request.getSessionIndex().isEmpty()) {
sessionStore.logoutByPrincipal(request.getNameID().getValue());
- } else {
+ } else {
sessionStore.logoutBySsoId(request.getSessionIndex());
}
@@ -169,7 +170,8 @@ public abstract class SamlAuthenticator {
binding.signatureAlgorithm(deployment.getSignatureAlgorithm())
.signWith(deployment.getSigningKeyPair())
.signDocument();
- if (deployment.getSignatureCanonicalizationMethod() != null) binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
+ if (deployment.getSignatureCanonicalizationMethod() != null)
+ binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
}
@@ -199,34 +201,80 @@ public abstract class SamlAuthenticator {
postBinding = true;
holder = extractPostBindingResponse(samlResponse);
}
- StatusResponseType statusResponse = (StatusResponseType)holder.getSamlObject();
+ final StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
// validate destination
if (!requestUri.equals(statusResponse.getDestination())) {
log.error("Request URI does not match SAML request destination");
return AuthOutcome.FAILED;
}
if (statusResponse instanceof ResponseType) {
- if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
- try {
- validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
- } catch (VerificationException e) {
- log.error("Failed to verify saml response signature", e);
- return AuthOutcome.FAILED;
+ try {
+ if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
+ try {
+ validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ } catch (VerificationException e) {
+ log.error("Failed to verify saml response signature", e);
+
+ challenge = new AuthChallenge() {
+ @Override
+ public boolean challenge(HttpFacade exchange) {
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
+ exchange.getRequest().setError(error);
+ exchange.getResponse().sendError(403);
+ return true;
+ }
+
+ @Override
+ public int getResponseCode() {
+ return 403;
+ }
+ };
+ return AuthOutcome.FAILED;
+ }
}
+ return handleLoginResponse((ResponseType) statusResponse);
+ } finally {
+ sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
- return handleLoginResponse((ResponseType)statusResponse);
} else {
- if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
+ if (sessionStore.isLoggingOut()) {
try {
- validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
- } catch (VerificationException e) {
- log.error("Failed to verify saml response signature", e);
+ if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
+ try {
+ validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ } catch (VerificationException e) {
+ log.error("Failed to verify saml response signature", e);
+ return AuthOutcome.FAILED;
+ }
+ }
+ return handleLogoutResponse(holder, statusResponse, relayState);
+ } finally {
+ sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
+ }
+
+ } else if (sessionStore.isLoggingIn()) {
+ try {
+ challenge = new AuthChallenge() {
+ @Override
+ public boolean challenge(HttpFacade exchange) {
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.ERROR_STATUS, statusResponse);
+ exchange.getRequest().setError(error);
+ exchange.getResponse().sendError(403);
+ return true;
+ }
+
+ @Override
+ public int getResponseCode() {
+ return 403;
+ }
+ };
return AuthOutcome.FAILED;
+ } finally {
+ sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
}
- // todo need to check that it is actually a LogoutResponse
- return handleLogoutResponse(holder, statusResponse, relayState);
+ return AuthOutcome.NOT_ATTEMPTED;
}
}
@@ -239,7 +287,7 @@ public abstract class SamlAuthenticator {
}
}
- protected AuthOutcome handleLoginResponse(ResponseType responseType) {
+ protected AuthOutcome handleLoginResponse(ResponseType responseType) {
AssertionType assertion = null;
try {
assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
@@ -248,7 +296,20 @@ public abstract class SamlAuthenticator {
}
} catch (Exception e) {
log.error("Error extracting SAML assertion, e");
- return AuthOutcome.FAILED;
+ challenge = new AuthChallenge() {
+ @Override
+ public boolean challenge(HttpFacade exchange) {
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.EXTRACTION_FAILURE);
+ exchange.getRequest().setError(error);
+ exchange.getResponse().sendError(403);
+ return true;
+ }
+
+ @Override
+ public int getResponseCode() {
+ return 403;
+ }
+ };
}
SubjectType subject = assertion.getSubject();
@@ -308,14 +369,14 @@ public abstract class SamlAuthenticator {
AuthnStatementType authn = null;
for (Object statement : assertion.getStatements()) {
if (statement instanceof AuthnStatementType) {
- authn = (AuthnStatementType)statement;
+ authn = (AuthnStatementType) statement;
break;
}
}
URI nameFormat = subjectNameID.getFormat();
- String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString();
+ String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString();
final SamlPrincipal principal = new SamlPrincipal(principalName, principalName, nameFormatString, attributes, friendlyAttributes);
String index = authn == null ? null : authn.getSessionIndex();
final String sessionIndex = index;
@@ -341,9 +402,9 @@ public abstract class SamlAuthenticator {
protected abstract void completeAuthentication(SamlSession account);
private String getAttributeValue(Object attrValue) {
- String value = null;
+ String value = null;
if (attrValue instanceof String) {
- value = (String)attrValue;
+ value = (String) attrValue;
} else if (attrValue instanceof Node) {
Node roleNode = (Node) attrValue;
value = roleNode.getFirstChild().getNodeValue();
@@ -372,6 +433,7 @@ public abstract class SamlAuthenticator {
protected SAMLDocumentHolder extractRedirectBindingResponse(String response) {
return SAMLRequestParser.parseRequestRedirectBinding(response);
}
+
protected SAMLDocumentHolder extractPostBindingResponse(String response) {
byte[] samlBytes = PostBindingUtil.base64Decode(response);
String xml = new String(samlBytes);
@@ -379,7 +441,6 @@ public abstract class SamlAuthenticator {
}
-
protected AuthOutcome initiateLogin() {
challenge = new InitiateLogin(deployment, sessionStore);
return AuthOutcome.NOT_ATTEMPTED;
@@ -445,5 +506,4 @@ public abstract class SamlAuthenticator {
}
-
}
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSessionStore.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSessionStore.java
index da200264ac..1a19464a99 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSessionStore.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSessionStore.java
@@ -1,6 +1,8 @@
package org.keycloak.adapters.saml;
import org.keycloak.adapters.spi.AdapterSessionStore;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import java.util.List;
@@ -9,6 +11,19 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface SamlSessionStore extends AdapterSessionStore {
+ public static final String CURRENT_ACTION = "SAML_CURRENT_ACTION";
+ public static final String SAML_LOGIN_ERROR_STATUS = "SAML_LOGIN_ERROR_STATUS";
+ public static final String SAML_LOGOUT_ERROR_STATUS = "SAML_LOGOUT_ERROR_STATUS";
+
+ enum CurrentAction {
+ NONE,
+ LOGGING_IN,
+ LOGGING_OUT
+ }
+ void setCurrentAction(CurrentAction action);
+ boolean isLoggingIn();
+ boolean isLoggingOut();
+
boolean isLoggedIn();
SamlSession getAccount();
void saveAccount(SamlSession account);
diff --git a/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java b/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
index 60cea893ee..2df0fad988 100755
--- a/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
+++ b/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
@@ -260,15 +260,6 @@ public abstract class AbstractSamlAuthenticator extends LoginAuthenticator {
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
challenge.challenge(facade);
- if (challenge.errorPage() && errorPage != null) {
- Response response = (Response)res;
- try {
- response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), errorPage)));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- }
}
return Authentication.SEND_CONTINUE;
}
diff --git a/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java b/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
index d86184b8ae..6e51f110f8 100755
--- a/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
+++ b/saml/client-adapter/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
@@ -8,6 +8,7 @@ import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpSession;
@@ -37,6 +38,28 @@ public class JettySamlSessionStore implements SamlSessionStore {
this.sessionManagement = sessionManagement;
}
+ @Override
+ public void setCurrentAction(CurrentAction action) {
+ if (action == CurrentAction.NONE && request.getSession(false) == null) return;
+ request.getSession().setAttribute(CURRENT_ACTION, action);
+ }
+
+ @Override
+ public boolean isLoggingIn() {
+ HttpSession session = request.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 = request.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 = request.getSession(false);
diff --git a/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/FilterSamlSessionStore.java b/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/FilterSamlSessionStore.java
index cbd036e882..e690db5d6f 100755
--- a/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/FilterSamlSessionStore.java
+++ b/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/FilterSamlSessionStore.java
@@ -7,6 +7,7 @@ import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.servlet.FilterSessionStore;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@@ -29,6 +30,28 @@ public class FilterSamlSessionStore extends FilterSessionStore implements SamlSe
this.idMapper = idMapper;
}
+ @Override
+ public void setCurrentAction(CurrentAction action) {
+ if (action == CurrentAction.NONE && request.getSession(false) == null) return;
+ request.getSession().setAttribute(CURRENT_ACTION, action);
+ }
+
+ @Override
+ public boolean isLoggingIn() {
+ HttpSession session = request.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 = request.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 = request.getSession(false);
diff --git a/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/SamlFilter.java b/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/SamlFilter.java
index bce4dbc10a..b2a0deda68 100755
--- a/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/SamlFilter.java
+++ b/saml/client-adapter/servlet-filter/src/main/java/org/keycloak/adapters/saml/servlet/SamlFilter.java
@@ -137,11 +137,6 @@ public class SamlFilter implements Filter {
if (challenge != null) {
log.fine("challenge");
challenge.challenge(facade);
- if (challenge.errorPage()) {
- response.sendError(challenge.getResponseCode());
- return;
- }
- log.fine("sending challenge");
return;
}
if (!facade.isEnded()) {
diff --git a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
index d231265623..3119ba7c9e 100755
--- a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
+++ b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
@@ -213,10 +213,6 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
loginConfig = request.getContext().getLoginConfig();
}
challenge.challenge(facade);
- if (challenge.errorPage()) {
- log.fine("error page");
- if (forwardToErrorPageInternal(request, response, loginConfig))return false;
- }
}
return false;
}
diff --git a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
index adbc441586..804acf36e1 100755
--- a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
+++ b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
@@ -9,6 +9,8 @@ import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.tomcat.CatalinaUserSessionManagement;
import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@@ -41,6 +43,28 @@ public class CatalinaSamlSessionStore implements SamlSessionStore {
this.facade = facade;
}
+ @Override
+ public void setCurrentAction(CurrentAction action) {
+ if (action == CurrentAction.NONE && request.getSession(false) == null) return;
+ request.getSession().setAttribute(CURRENT_ACTION, action);
+ }
+
+ @Override
+ public boolean isLoggingIn() {
+ HttpSession session = request.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 = request.getSession(false);
+ if (session == null) return false;
+ CurrentAction action = (CurrentAction)session.getAttribute(CURRENT_ACTION);
+ return action == CurrentAction.LOGGING_OUT;
+ }
+
@Override
public void logoutAccount() {
Session sessionInternal = request.getSessionInternal(false);
diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/AbstractSamlAuthMech.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/AbstractSamlAuthMech.java
index 721f0c0ac4..8f1929af58 100755
--- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/AbstractSamlAuthMech.java
+++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/AbstractSamlAuthMech.java
@@ -55,10 +55,6 @@ public abstract class AbstractSamlAuthMech implements AuthenticationMechanism {
public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) {
AuthChallenge challenge = exchange.getAttachment(KEYCLOAK_CHALLENGE_ATTACHMENT_KEY);
if (challenge != null) {
- if (challenge.errorPage() && errorPage != null) {
- Integer code = servePage(exchange, errorPage);
- return new ChallengeResult(true, code);
- }
UndertowHttpFacade facade = createFacade(exchange);
if (challenge.challenge(facade)) {
return new ChallengeResult(true, exchange.getResponseCode());
diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
index 8afcc1f40e..34d718b59d 100755
--- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
+++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
@@ -13,9 +13,12 @@ import org.keycloak.adapters.saml.SamlSession;
import org.keycloak.adapters.saml.SamlSessionStore;
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
import org.keycloak.common.util.KeycloakUriBuilder;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import java.io.IOException;
import java.security.Principal;
import java.util.LinkedList;
import java.util.List;
@@ -34,6 +37,7 @@ public class ServletSamlSessionStore implements SamlSessionStore {
private final SecurityContext securityContext;
private final SessionIdMapper idMapper;
+
public ServletSamlSessionStore(HttpServerExchange exchange, UndertowUserSessionManagement sessionManagement,
SecurityContext securityContext,
SessionIdMapper idMapper) {
@@ -43,6 +47,28 @@ public class ServletSamlSessionStore implements SamlSessionStore {
this.idMapper = idMapper;
}
+ @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);
@@ -170,8 +196,18 @@ public class ServletSamlSessionStore implements SamlSessionStore {
}
protected HttpSession getSession(boolean create) {
- final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
- HttpServletRequest req = (HttpServletRequest) servletRequestContext.getServletRequest();
+ 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();
+ }
}
diff --git a/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java b/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java
index 2ce85eb6b9..482834b873 100755
--- a/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java
+++ b/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusCodeType.java
@@ -17,6 +17,7 @@
*/
package org.keycloak.dom.saml.v2.protocol;
+import java.io.Serializable;
import java.net.URI;
/**
@@ -39,7 +40,7 @@ import java.net.URI;
* </complexType>
*
*/
-public class StatusCodeType {
+public class StatusCodeType implements Serializable {
protected StatusCodeType statusCode;
protected URI value;
diff --git a/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java b/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java
index 9918879e43..2e2eab97ff 100755
--- a/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java
+++ b/saml/saml-core/src/main/java/org/keycloak/dom/saml/v2/protocol/StatusType.java
@@ -17,6 +17,8 @@
*/
package org.keycloak.dom.saml.v2.protocol;
+import java.io.Serializable;
+
/**
*
* Java class for StatusType complex type.
@@ -38,7 +40,7 @@ package org.keycloak.dom.saml.v2.protocol;
* </complexType>
*
*/
-public class StatusType {
+public class StatusType implements Serializable {
protected String statusMessage;
protected StatusCodeType statusCode;
diff --git a/saml/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java b/saml/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
index db7ac7ebf0..237365673b 100755
--- a/saml/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
+++ b/saml/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
@@ -1,6 +1,12 @@
package org.keycloak.saml;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.protocol.StatusCodeType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusType;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
import org.keycloak.saml.processing.core.saml.v2.common.IDGenerator;
@@ -9,8 +15,11 @@ import org.keycloak.saml.processing.core.saml.v2.holders.IDPInfoHolder;
import org.keycloak.saml.processing.core.saml.v2.holders.IssuerInfoHolder;
import org.keycloak.saml.processing.core.saml.v2.holders.SPInfoHolder;
import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
import org.w3c.dom.Document;
+import java.net.URI;
+
/**
* @author Bill Burke
* @version $Revision: 1 $
@@ -38,29 +47,25 @@ public class SAML2ErrorResponseBuilder {
public Document buildDocument() throws ProcessingException {
- Document samlResponse = null;
- ResponseType responseType = null;
- SAML2Response saml2Response = new SAML2Response();
+ try {
+ StatusResponseType statusResponse = new StatusResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
- // Create a response type
- String id = IDGenerator.create("ID_");
+ statusResponse.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
+ NameIDType issuer = new NameIDType();
+ issuer.setValue(this.issuer);
- IssuerInfoHolder issuerHolder = new IssuerInfoHolder(issuer);
- issuerHolder.setStatusCode(status);
+ statusResponse.setIssuer(issuer);
+ statusResponse.setDestination(destination);
- IDPInfoHolder idp = new IDPInfoHolder();
- idp.setNameIDFormatValue(null);
- idp.setNameIDFormat(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get());
+ SAML2Response saml2Response = new SAML2Response();
+ return saml2Response.convert(statusResponse);
+ } catch (ConfigurationException e) {
+ throw new ProcessingException(e);
+ } catch (ParsingException e) {
+ throw new ProcessingException(e);
+ }
- SPInfoHolder sp = new SPInfoHolder();
- sp.setResponseDestinationURI(destination);
-
- responseType = saml2Response.createResponseType(id);
- responseType.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
- responseType.setDestination(destination);
-
- return samlResponse;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index 816be92945..31b05508d8 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -24,6 +24,7 @@ package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.junit.rules.ExternalResource;
import org.keycloak.OAuth2Constants;
+import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.common.Version;
import org.keycloak.representations.VersionRepresentation;
import org.keycloak.admin.client.Keycloak;
@@ -42,6 +43,7 @@ import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.AccountSessionsPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
+import org.keycloak.testsuite.rule.ErrorServlet;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
@@ -385,6 +387,7 @@ public class AdapterTestStrategy extends ExternalResource {
* @throws Exception
*/
public void testNullBearerTokenCustomErrorPage() throws Exception {
+ ErrorServlet.authError = null;
Client client = ClientBuilder.newClient();
WebTarget target = client.target(APP_SERVER_BASE_URL + "/customer-db-error-page/");
@@ -396,11 +399,15 @@ public class AdapterTestStrategy extends ExternalResource {
response.close();
response = client.target(location).request().get();
}
- Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(401, response.getStatus());
String errorPageResponse = response.readEntity(String.class);
Assert.assertTrue(errorPageResponse.contains("Error Page"));
response.close();
+ Assert.assertNotNull(ErrorServlet.authError);
+ OIDCAuthenticationError error = (OIDCAuthenticationError)ErrorServlet.authError;
+ Assert.assertEquals(OIDCAuthenticationError.Reason.NO_BEARER_TOKEN, error.getReason());
+ ErrorServlet.authError = null;
response = target.request().header(HttpHeaders.AUTHORIZATION, "Bearer null").get();
// TODO: follow redirects automatically if possible
if (response.getStatus() == 302) {
@@ -408,10 +415,13 @@ public class AdapterTestStrategy extends ExternalResource {
response.close();
response = client.target(location).request().get();
}
- Assert.assertEquals(200, response.getStatus());
+ Assert.assertEquals(401, response.getStatus());
errorPageResponse = response.readEntity(String.class);
Assert.assertTrue(errorPageResponse.contains("Error Page"));
response.close();
+ Assert.assertNotNull(ErrorServlet.authError);
+ error = (OIDCAuthenticationError)ErrorServlet.authError;
+ Assert.assertEquals(OIDCAuthenticationError.Reason.INVALID_TOKEN, error.getReason());
client.close();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
index f97a05ebd7..0d20f7a7d3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
@@ -48,12 +48,7 @@ public class SamlAdapterTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
@@ -61,11 +56,16 @@ public class SamlAdapterTest {
testStrategy.testPostSimpleUnauthorized( new SamlAdapterTestStrategy.CheckAuthError() {
@Override
public void check(WebDriver driver) {
- Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
+ String pageSource = driver.getPageSource();
+ Assert.assertTrue(pageSource.contains("Error Page"));
}
});
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
@Test
public void testMetadataPostSignedLoginLogout() throws Exception {
testStrategy.testMetadataPostSignedLoginLogout();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
index 4791c2a70a..b63c9609cb 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
@@ -1,26 +1,17 @@
package org.keycloak.testsuite.keycloaksaml;
import org.apache.commons.io.IOUtils;
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
import org.junit.rules.ExternalResource;
-import org.keycloak.Config;
+import org.keycloak.adapters.saml.SamlAuthenticationError;
import org.keycloak.adapters.saml.SamlPrincipal;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
import org.keycloak.protocol.saml.mappers.GroupMembershipMapper;
import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
@@ -28,33 +19,28 @@ import org.keycloak.protocol.saml.mappers.HardcodedRole;
import org.keycloak.protocol.saml.mappers.RoleListMapper;
import org.keycloak.protocol.saml.mappers.RoleNameMapper;
import org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper;
-import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.saml.BaseSAML2BindingBuilder;
+import org.keycloak.saml.SAML2ErrorResponseBuilder;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
import org.keycloak.testsuite.KeycloakServer;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
+import org.keycloak.testsuite.rule.ErrorServlet;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
-import org.keycloak.util.JsonSerialization;
import org.openqa.selenium.WebDriver;
+import org.w3c.dom.Document;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
-import java.io.InputStream;
+import java.net.URI;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -115,6 +101,33 @@ public class SamlAdapterTestStrategy extends ExternalResource {
Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
}
+ public void testErrorHandling() throws Exception {
+ ErrorServlet.authError = null;
+ Client client = ClientBuilder.newClient();
+ // make sure
+ Response response = client.target(APP_SERVER_BASE_URL + "/employee-sig/").request().get();
+ response.close();
+ SAML2ErrorResponseBuilder builder = new SAML2ErrorResponseBuilder()
+ .destination(APP_SERVER_BASE_URL + "/employee-sig/")
+ .issuer(AUTH_SERVER_URL + "/realms/demo")
+ .status(JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get());
+ BaseSAML2BindingBuilder binding = new BaseSAML2BindingBuilder()
+ .relayState(null);
+ Document document = builder.buildDocument();
+ URI uri = binding.redirectBinding(document).generateURI(APP_SERVER_BASE_URL + "/employee-sig/", false);
+ response = client.target(uri).request().get();
+ String errorPage = response.readEntity(String.class);
+ response.close();
+ Assert.assertTrue(errorPage.contains("Error Page"));
+ client.close();
+ Assert.assertNotNull(ErrorServlet.authError);
+ SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
+ Assert.assertEquals(SamlAuthenticationError.Reason.ERROR_STATUS, error.getReason());
+ Assert.assertNotNull(error.getStatus());
+ ErrorServlet.authError = null;
+
+ }
+
public void testPostSimpleLoginLogout() {
driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post/");
assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
@@ -383,13 +396,17 @@ public class SamlAdapterTestStrategy extends ExternalResource {
void check(WebDriver driver);
}
- public void testPostBadRealmSignature(CheckAuthError error) {
+ public void testPostBadRealmSignature() {
+ ErrorServlet.authError = null;
driver.navigate().to(APP_SERVER_BASE_URL + "/bad-realm-sales-post-sig/");
assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
loginPage.login("bburke", "password");
assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/bad-realm-sales-post-sig/");
System.out.println(driver.getPageSource());
- error.check(driver);
+ Assert.assertNotNull(ErrorServlet.authError);
+ SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
+ Assert.assertEquals(SamlAuthenticationError.Reason.INVALID_SIGNATURE, error.getReason());
+ ErrorServlet.authError = null;
}
public void testMetadataPostSignedLoginLogout() throws Exception {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
index 34d17f0aff..5a1d01f807 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
@@ -115,6 +115,7 @@ public abstract class SamlKeycloakRule extends AbstractKeycloakRule {
.addServlets(regularServletInfo)
.addSecurityConstraint(constraint)
.addServletExtension(new SamlServletExtension());
+ addErrorPage("/error.html", deploymentInfo);
server.getServer().deploy(deploymentInfo);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index fc2dc4106d..155bdf117f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -1,6 +1,7 @@
package org.keycloak.testsuite.rule;
import io.undertow.servlet.api.DeploymentInfo;
+import io.undertow.servlet.api.ErrorPage;
import io.undertow.servlet.api.FilterInfo;
import io.undertow.servlet.api.LoginConfig;
import io.undertow.servlet.api.SecurityConstraint;
@@ -156,7 +157,7 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
return new DeploymentBuilder();
}
- public void addErrorPage(DeploymentInfo di) {
+ public void addErrorPage(String errorPage, DeploymentInfo di) {
ServletInfo servlet = new ServletInfo("Error Page", ErrorServlet.class);
servlet.addMapping("/error.html");
SecurityConstraint constraint = new SecurityConstraint();
@@ -166,6 +167,11 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
constraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT);
di.addSecurityConstraint(constraint);
di.addServlet(servlet);
+ di
+ .addErrorPage(new ErrorPage(errorPage, 400))
+ .addErrorPage(new ErrorPage(errorPage, 401))
+ .addErrorPage(new ErrorPage(errorPage, 403))
+ .addErrorPage(new ErrorPage(errorPage, 500));
}
public void deployJaxrsApplication(String name, String contextPath, Class extends Application> applicationClass, Map initParams) {
@@ -346,9 +352,9 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
constraint.addRoleAllowed(role);
di.addSecurityConstraint(constraint);
}
- LoginConfig loginConfig = new LoginConfig("KEYCLOAK", "demo", null, errorPage);
+ LoginConfig loginConfig = new LoginConfig("KEYCLOAK", "demo", null, null);
di.setLoginConfig(loginConfig);
- addErrorPage(di);
+ addErrorPage(errorPage, di);
server.getServer().deploy(di);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/ErrorServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/ErrorServlet.java
index 47f7135be6..68410d48bf 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/ErrorServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/ErrorServlet.java
@@ -1,5 +1,7 @@
package org.keycloak.testsuite.rule;
+import org.keycloak.adapters.spi.AuthenticationError;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -12,10 +14,11 @@ import java.io.PrintWriter;
* @author Marek Posolda
*/
public class ErrorServlet extends HttpServlet {
+ public static AuthenticationError authError;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
+ authError = (AuthenticationError)req.getAttribute(AuthenticationError.class.getName());
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
@@ -25,4 +28,9 @@ public class ErrorServlet extends HttpServlet {
}
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ doGet(req, resp);
+ }
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
index 88f97a6e01..9a47b4414e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
@@ -53,12 +53,7 @@ public class SamlAdapterTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
@@ -72,7 +67,7 @@ public class SamlAdapterTest {
testStrategy.testPostSimpleUnauthorized(new SamlAdapterTestStrategy.CheckAuthError() {
@Override
public void check(WebDriver driver) {
- Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
+ Assert.assertTrue(driver.getPageSource().contains("Error Page"));
}
});
} finally {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlKeycloakRule.java
index e1fd3c85ff..a348408ce6 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlKeycloakRule.java
@@ -114,6 +114,7 @@ public abstract class SamlKeycloakRule extends AbstractKeycloakRule {
.addFilter(samlFilter)
.addFilterUrlMapping("saml-filter", "/*", DispatcherType.REQUEST)
.addServletExtension(new SamlServletExtension());
+ addErrorPage("/error.html", deploymentInfo);
server.getServer().deploy(deploymentInfo);
}
diff --git a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index 1506b0ce6a..6228a688ef 100755
--- a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -104,6 +104,11 @@ public class JettySamlTest {
} catch (Exception e) {}
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSimpleLoginLogout() {
testStrategy.testPostSimpleLoginLogout();
@@ -166,12 +171,7 @@ public class JettySamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index f44a60bba0..e41448a81c 100755
--- a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..71eff5281a 100755
--- a/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,11 +10,40 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty81/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index e71887e203..40edb45d0a 100755
--- a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -103,6 +103,11 @@ public class JettySamlTest {
} catch (Exception e) {}
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSimpleLoginLogout() {
testStrategy.testPostSimpleLoginLogout();
@@ -165,12 +170,7 @@ public class JettySamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index f44a60bba0..e41448a81c 100755
--- a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..2f7ef22b7f 100755
--- a/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,12 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
-
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
/*
diff --git a/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty91/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index e71887e203..cd3c11ace2 100755
--- a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -103,6 +103,11 @@ public class JettySamlTest {
} catch (Exception e) {}
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSimpleLoginLogout() {
testStrategy.testPostSimpleLoginLogout();
@@ -165,12 +170,7 @@ public class JettySamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature( );
}
@Test
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index f44a60bba0..e41448a81c 100755
--- a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/jetty/jetty92/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index c72ab019d9..0e6973a083 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -112,6 +112,11 @@ public class TomcatSamlTest {
testStrategy.testPostSignedLoginLogoutPersistentNameID();
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSignedLoginLogoutEmailNameID() {
testStrategy.testPostSignedLoginLogoutEmailNameID();
@@ -149,12 +154,7 @@ public class TomcatSamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index c2cef86e5f..fa6a47b406 100755
--- a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
@@ -44,11 +64,7 @@
BASIC
demo
-
- /error.html
- /error.html
-
-
+
admin
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..2f7ef22b7f 100755
--- a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,12 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
-
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
/*
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index f9cb8536ee..2483333c96 100755
--- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -92,6 +92,11 @@ public class TomcatSamlTest {
}
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSimpleLoginLogout() {
testStrategy.testPostSimpleLoginLogout();
@@ -154,12 +159,7 @@ public class TomcatSamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index c2cef86e5f..fdd69a37d3 100755
--- a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/tomcat7/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/tomcat7/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/tomcat7/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/tomcat7/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/tomcat7/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/tomcat7/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/tomcat7/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/tomcat7/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index 405c6ee9db..a4a38299af 100755
--- a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -92,6 +92,11 @@ public class TomcatSamlTest {
@Rule
public SamlAdapterTestStrategy testStrategy = new SamlAdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8082", keycloakRule);
+ @Test
+ public void testErrorHandling() throws Exception {
+ testStrategy.testErrorHandling();
+ }
+
@Test
public void testPostSimpleLoginLogout() {
testStrategy.testPostSimpleLoginLogout();
@@ -154,12 +159,7 @@ public class TomcatSamlTest {
@Test
public void testPostBadRealmSignature() {
- testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
- @Override
- public void check(WebDriver driver) {
- Assert.assertEquals(driver.getPageSource(), "");
- }
- });
+ testStrategy.testPostBadRealmSignature();
}
@Test
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
index c2cef86e5f..fdd69a37d3 100755
--- a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml
@@ -25,6 +25,26 @@
/error.html
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
+
Users
diff --git a/testsuite/tomcat8/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/tomcat8/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/tomcat8/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
+++ b/testsuite/tomcat8/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users
diff --git a/testsuite/tomcat8/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/tomcat8/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
index 86db4a46a4..ed4f018749 100755
--- a/testsuite/tomcat8/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
+++ b/testsuite/tomcat8/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -10,11 +10,39 @@
SendUsernameServlet
org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+ Error Servlet
+ org.keycloak.testsuite.rule.ErrorServlet
+
SendUsernameServlet
/*
+
+ Error Servlet
+ /error.html
+
+
+
+ 400
+ /error.html
+
+
+
+ 401
+ /error.html
+
+
+
+ 403
+ /error.html
+
+
+
+ 500
+ /error.html
+
Users