diff --git a/core/src/main/java/org/keycloak/util/HtmlUtils.java b/core/src/main/java/org/keycloak/util/HtmlUtils.java
old mode 100644
new mode 100755
index 7da97b7e88..2387482df4
--- a/core/src/main/java/org/keycloak/util/HtmlUtils.java
+++ b/core/src/main/java/org/keycloak/util/HtmlUtils.java
@@ -34,7 +34,17 @@ public class HtmlUtils {
for (int i = 0; i < value.length(); i++) {
char chr = value.charAt(i);
- if (chr != '\'' && chr != '"' && chr != '<' && chr != '>' && chr != '/') {
+ if (chr == '<') {
+ escaped.append("<");
+ } else if (chr == '>') {
+ escaped.append(">");
+ } else if (chr == '"') {
+ escaped.append(""");
+ } else if (chr == '\'') {
+ escaped.append("'");
+ } else if (chr == '&') {
+ escaped.append("&");
+ } else {
escaped.append(chr);
}
}
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
index bfa184b3b0..09b033b9d7 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -504,6 +504,7 @@ public class SamlService {
@QueryParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse,
@QueryParam(GeneralConstants.RELAY_STATE) String relayState) {
logger.debug("SAML GET");
+ //String uri = uriInfo.getRequestUri().toString();
return new RedirectBindingProtocol().execute(samlRequest, samlResponse, relayState);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index 54700417d0..e82b04a8d4 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -1,473 +1,495 @@
-package org.keycloak.testsuite.saml;
-
-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.keycloak.Config;
-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.HardcodedAttributeMapper;
-import org.keycloak.protocol.saml.mappers.HardcodedRole;
-import org.keycloak.protocol.saml.mappers.RoleListMapper;
-import org.keycloak.protocol.saml.mappers.RoleNameMapper;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.WebDriver;
-import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
-import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
-import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
-import org.keycloak.dom.saml.v2.assertion.AssertionType;
-import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
-import org.keycloak.dom.saml.v2.assertion.AttributeType;
-import org.keycloak.dom.saml.v2.protocol.ResponseType;
-import org.keycloak.saml.processing.web.util.PostBindingUtil;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-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.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SamlBindingTest {
-
- @ClassRule
- public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
- @Override
- public void initWars() {
- ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
-
- initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
- //initializeSamlSecuredWar("/saml/simple-get", "/employee", "employee.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
- initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
- uploadSP();
- server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
-
-
-
- }
-
- @Override
- public String getRealmJson() {
- return "/saml/testsaml.json";
- }
- };
-
- public static class SamlSPFacade extends HttpServlet {
- public static String samlResponse;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- private void handler(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("********* HERE ******");
- if (req.getParameterMap().isEmpty()) {
- System.out.println("redirecting");
- resp.setStatus(302);
- resp.setHeader("Location", "http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
- return;
- }
- System.out.println("received response");
- samlResponse = req.getParameter("SAMLResponse");
- }
- }
-
- @Rule
- public WebRule webRule = new WebRule(this);
- @WebResource
- protected WebDriver driver;
- @WebResource
- protected LoginPage loginPage;
-
- protected void checkLoggedOut(String mainUrl) {
- String pageSource = driver.getPageSource();
- System.out.println("*** logout pagesouce ***");
- System.out.println(pageSource);
- System.out.println("driver url: " + driver.getCurrentUrl());
- Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
- driver.navigate().to(mainUrl);
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- }
-
-
- @Test
- public void testPostSimpleLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post/");
- }
- @Test
- public void testPostSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig/");
-
- }
- @Test
- public void testPostSignedLoginLogoutTransientNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
-
- }
- @Test
- public void testPostSignedLoginLogoutPersistentNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
-
- }
- @Test
- public void testPostSignedLoginLogoutEmailNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-email/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
-
- }
-
-
- @Test
- public void testAttributes() throws Exception {
- // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
- // at the assertions sent. This is because Picketlink, AFAICT, does not give you any way to get access to
- // the assertion.
-
- {
- SamlSPFacade.samlResponse = null;
- driver.navigate().to("http://localhost:8081/employee/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println(driver.getCurrentUrl());
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
- Assert.assertNotNull(SamlSPFacade.samlResponse);
- SAML2Response saml2Response = new SAML2Response();
- byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
- ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
- Assert.assertTrue(rt.getAssertions().size() == 1);
- AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
- // test attributes and roles
-
- boolean email = false;
- boolean phone = false;
- boolean userRole = false;
- boolean managerRole = false;
- for (AttributeStatementType statement : assertion.getAttributeStatements()) {
- for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
- AttributeType attr = choice.getAttribute();
- if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
- Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
- Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
- Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
- email = true;
- } else if (attr.getName().equals("phone")) {
- Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
- Assert.assertEquals(attr.getAttributeValue().get(0), "617");
- phone = true;
- } else if (attr.getName().equals("Role")) {
- if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
- if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
- }
- }
-
- }
-
- Assert.assertTrue(email);
- Assert.assertTrue(phone);
- Assert.assertTrue(userRole);
- Assert.assertTrue(managerRole);
- }
-
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
- for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
- if (mapper.getName().equals("role-list")) {
- app.removeProtocolMapper(mapper);
- mapper.setId(null);
- mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
- mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
- app.addProtocolMapper(mapper);
- }
- }
- app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
- app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
- }
- }, "demo");
-
- System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
-
- {
- SamlSPFacade.samlResponse = null;
- driver.navigate().to("http://localhost:8081/employee/");
- System.out.println(driver.getCurrentUrl());
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
- Assert.assertNotNull(SamlSPFacade.samlResponse);
- SAML2Response saml2Response = new SAML2Response();
- byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
- ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
- Assert.assertTrue(rt.getAssertions().size() == 1);
- AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
- // test attributes and roles
-
- boolean userRole = false;
- boolean managerRole = false;
- boolean single = false;
- boolean hardcodedRole = false;
- boolean hardcodedAttribute = false;
- boolean peeOn = false;
- for (AttributeStatementType statement : assertion.getAttributeStatements()) {
- for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
- AttributeType attr = choice.getAttribute();
- if (attr.getName().equals("memberOf")) {
- if (single) Assert.fail("too many role attributes");
- single = true;
- for (Object value : attr.getAttributeValue()) {
- if (value.equals("el-jefe")) managerRole = true;
- if (value.equals("user")) userRole = true;
- if (value.equals("hardcoded-role")) hardcodedRole = true;
- if (value.equals("pee-on")) peeOn = true;
- }
- } else if (attr.getName().equals("hardcoded-attribute")) {
- hardcodedAttribute = true;
- Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
- }
- }
-
- }
-
- Assert.assertTrue(single);
- Assert.assertTrue(hardcodedAttribute);
- Assert.assertTrue(hardcodedRole);
- Assert.assertTrue(peeOn);
- Assert.assertTrue(userRole);
- Assert.assertTrue(managerRole);
- }
- }
-
- @Test
- public void testRedirectSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFrontNoSSO() {
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig-front/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFront() {
- // visit 1st app an logg in
- System.out.println("visit 1st app ");
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println("login to form");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 2nd app
- System.out.println("visit 2nd app ");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 3rd app
- System.out.println("visit 3rd app ");
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // logout of first app
- System.out.println("GLO");
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
-
- }
-
- @Test
- public void testPostEncryptedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-enc/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-enc/");
-
- }
- @Test
- public void testPostBadClientSignature() {
- driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- Assert.assertEquals(driver.getTitle(), "We're sorry...");
-
- }
-
- @Test
- public void testPostBadRealmSignature() {
- driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("null"));
- }
-
- private static String createToken() {
- KeycloakSession session = keycloakRule.startSession();
- try {
- RealmManager manager = new RealmManager(session);
-
- RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
- ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
- TokenManager tm = new TokenManager();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
- clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
- UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
- return tm.encodeToken(adminRealm, token);
- } finally {
- keycloakRule.stopSession(session, true);
- }
- }
-
-
- @Test
- public void testMetadataPostSignedLoginLogout() throws Exception {
-
- driver.navigate().to("http://localhost:8081/sales-metadata/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
- String pageSource = driver.getPageSource();
- Assert.assertTrue(pageSource.contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-metadata/");
-
- }
-
- public static void uploadSP() {
- String token = createToken();
- final String authHeader = "Bearer " + token;
- ClientRequestFilter authFilter = new ClientRequestFilter() {
- @Override
- public void filter(ClientRequestContext requestContext) throws IOException {
- requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
- }
- };
- Client client = ClientBuilder.newBuilder().register(authFilter).build();
- UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
- WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
-
-
- MultipartFormDataOutput formData = new MultipartFormDataOutput();
- InputStream is = SamlBindingTest.class.getResourceAsStream("/saml/sp-metadata.xml");
- Assert.assertNotNull(is);
- formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
-
- WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
- System.out.println(upload.getUri());
- Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
- Assert.assertEquals(204, response.getStatus());
- response.close();
- client.close();
- }
-
-
-}
+package org.keycloak.testsuite.saml;
+
+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.keycloak.Config;
+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.HardcodedAttributeMapper;
+import org.keycloak.protocol.saml.mappers.HardcodedRole;
+import org.keycloak.protocol.saml.mappers.RoleListMapper;
+import org.keycloak.protocol.saml.mappers.RoleNameMapper;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.admin.AdminRoot;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.saml.processing.web.util.PostBindingUtil;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlBindingTest {
+
+ @ClassRule
+ public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
+ @Override
+ public void initWars() {
+ ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
+
+ initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
+ //initializeSamlSecuredWar("/saml/simple-get", "/employee", "employee.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
+ initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
+ uploadSP();
+ server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
+
+
+
+ }
+
+ @Override
+ public String getRealmJson() {
+ return "/saml/testsaml.json";
+ }
+ };
+
+ public static class SamlSPFacade extends HttpServlet {
+ public static String samlResponse;
+ public static String RELAY_STATE = "http://test.com/foo/bar";
+ public static String sentRelayState;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ private void handler(HttpServletRequest req, HttpServletResponse resp) {
+ System.out.println("********* HERE ******");
+ if (req.getParameterMap().isEmpty()) {
+ System.out.println("redirecting");
+ resp.setStatus(302);
+ // Redirect
+ // UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVLRTsIwFP2Vpe%2BjG4wxG0YyWYxL0BBAH3wx3XYnTbp29nYof%2B8YEvEBNOlD03vOveec2ynyWjYsae1WreC9BbTOZy0Vsr4Qk9YopjkKZIrXgMwWbJ08LNhw4LHGaKsLLcmRch3MEcFYoRVxktN1rhW2NZg1mJ0o4Gm1iMnW2oZRKnXB5VajZZEX%2BRTqRuo9ACVO2mkUih%2F4l9C8s0MNcFkjLaHW9KSUHlwR506bAnrPMam4RCBOlsYkS1%2BD3MvLcDJxAx9KN4jCkXszrG5cP%2BCVH4y8IM8PYFx2dsQOfuiILWQKLVc2JkPPH7te6HrRxh%2BzUdidwSSIXoiz%2FBZyK1Qp1Nv1yPIjCNn9ZrN0V1AKA4UlzjMY7N13IDKbHjyxXoA5291%2FtzH7I%2FApPet%2FHNawx65hli61FMXeSaTUH%2FMubtvlYU0LfcA1t5cl%2BAO%2FfxGlW%2FVQ1ipsoBCVgJLQ2XHo7385%2BwI%3D");
+ UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
+ builder.queryParam("RelayState", RELAY_STATE);
+ resp.setHeader("Location", builder.build().toString());
+ return;
+ }
+ System.out.println("received response");
+ samlResponse = req.getParameter("SAMLResponse");
+ sentRelayState = req.getParameter("RelayState");
+ }
+ }
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+ @WebResource
+ protected WebDriver driver;
+ @WebResource
+ protected LoginPage loginPage;
+
+ protected void checkLoggedOut(String mainUrl) {
+ String pageSource = driver.getPageSource();
+ System.out.println("*** logout pagesouce ***");
+ System.out.println(pageSource);
+ System.out.println("driver url: " + driver.getCurrentUrl());
+ Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
+ driver.navigate().to(mainUrl);
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ }
+
+
+ @Test
+ public void testPostSimpleLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post/");
+ }
+ @Test
+ public void testPostSignedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutTransientNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutPersistentNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutEmailNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-email/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
+
+ }
+
+ @Test
+ public void testRelayStateEncoding() throws Exception {
+ // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
+ // at the relay state
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println(driver.getCurrentUrl());
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertEquals(SamlSPFacade.sentRelayState, SamlSPFacade.RELAY_STATE);
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+
+ }
+
+
+ @Test
+ public void testAttributes() throws Exception {
+ // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
+ // at the assertions sent. This is because Picketlink, AFAICT, does not give you any way to get access to
+ // the assertion.
+
+ {
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println(driver.getCurrentUrl());
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+ SAML2Response saml2Response = new SAML2Response();
+ byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+ ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+ Assert.assertTrue(rt.getAssertions().size() == 1);
+ AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+ // test attributes and roles
+
+ boolean email = false;
+ boolean phone = false;
+ boolean userRole = false;
+ boolean managerRole = false;
+ for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+ for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+ AttributeType attr = choice.getAttribute();
+ if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
+ Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
+ Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
+ Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
+ email = true;
+ } else if (attr.getName().equals("phone")) {
+ Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
+ Assert.assertEquals(attr.getAttributeValue().get(0), "617");
+ phone = true;
+ } else if (attr.getName().equals("Role")) {
+ if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
+ if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
+ }
+ }
+
+ }
+
+ Assert.assertTrue(email);
+ Assert.assertTrue(phone);
+ Assert.assertTrue(userRole);
+ Assert.assertTrue(managerRole);
+ }
+
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
+ for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
+ if (mapper.getName().equals("role-list")) {
+ app.removeProtocolMapper(mapper);
+ mapper.setId(null);
+ mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
+ mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
+ app.addProtocolMapper(mapper);
+ }
+ }
+ app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
+ app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
+ }
+ }, "demo");
+
+ System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
+
+ {
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ System.out.println(driver.getCurrentUrl());
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+ SAML2Response saml2Response = new SAML2Response();
+ byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+ ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+ Assert.assertTrue(rt.getAssertions().size() == 1);
+ AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+ // test attributes and roles
+
+ boolean userRole = false;
+ boolean managerRole = false;
+ boolean single = false;
+ boolean hardcodedRole = false;
+ boolean hardcodedAttribute = false;
+ boolean peeOn = false;
+ for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+ for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+ AttributeType attr = choice.getAttribute();
+ if (attr.getName().equals("memberOf")) {
+ if (single) Assert.fail("too many role attributes");
+ single = true;
+ for (Object value : attr.getAttributeValue()) {
+ if (value.equals("el-jefe")) managerRole = true;
+ if (value.equals("user")) userRole = true;
+ if (value.equals("hardcoded-role")) hardcodedRole = true;
+ if (value.equals("pee-on")) peeOn = true;
+ }
+ } else if (attr.getName().equals("hardcoded-attribute")) {
+ hardcodedAttribute = true;
+ Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
+ }
+ }
+
+ }
+
+ Assert.assertTrue(single);
+ Assert.assertTrue(hardcodedAttribute);
+ Assert.assertTrue(hardcodedRole);
+ Assert.assertTrue(peeOn);
+ Assert.assertTrue(userRole);
+ Assert.assertTrue(managerRole);
+ }
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig/");
+
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFrontNoSSO() {
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig-front/");
+
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFront() {
+ // visit 1st app an logg in
+ System.out.println("visit 1st app ");
+ driver.navigate().to("http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println("login to form");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 2nd app
+ System.out.println("visit 2nd app ");
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 3rd app
+ System.out.println("visit 3rd app ");
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // logout of first app
+ System.out.println("GLO");
+ driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig/");
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+
+ }
+
+ @Test
+ public void testPostEncryptedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post-enc/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-enc/");
+
+ }
+ @Test
+ public void testPostBadClientSignature() {
+ driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ Assert.assertEquals(driver.getTitle(), "We're sorry...");
+
+ }
+
+ @Test
+ public void testPostBadRealmSignature() {
+ driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("null"));
+ }
+
+ private static String createToken() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+
+ RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
+ ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
+ TokenManager tm = new TokenManager();
+ UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+ ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
+ UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
+ return tm.encodeToken(adminRealm, token);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void testMetadataPostSignedLoginLogout() throws Exception {
+
+ driver.navigate().to("http://localhost:8081/sales-metadata/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
+ String pageSource = driver.getPageSource();
+ Assert.assertTrue(pageSource.contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-metadata/");
+
+ }
+
+ public static void uploadSP() {
+ String token = createToken();
+ final String authHeader = "Bearer " + token;
+ ClientRequestFilter authFilter = new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
+ }
+ };
+ Client client = ClientBuilder.newBuilder().register(authFilter).build();
+ UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
+ WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
+
+
+ MultipartFormDataOutput formData = new MultipartFormDataOutput();
+ InputStream is = SamlBindingTest.class.getResourceAsStream("/saml/sp-metadata.xml");
+ Assert.assertNotNull(is);
+ formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
+
+ WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
+ System.out.println(upload.getUri());
+ Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
+ Assert.assertEquals(204, response.getStatus());
+ response.close();
+ client.close();
+ }
+
+
+}
diff --git a/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
index e2e7e3ba40..2dd9522e4f 100755
--- a/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
+++ b/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
@@ -1,6 +1,6 @@
+ ServerEnvironment="tomcat" BindingType="REDIRECT" SupportsSignatures="true" IDPUsesPostBinding="false">
${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml}
${employee-sig.url::http://localhost:8081/employee-sig/}
diff --git a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
index 7636260689..ade45d1cd8 100755
--- a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
+++ b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
@@ -1,6 +1,6 @@
+ ServerEnvironment="tomcat" BindingType="REDIRECT" IDPUsesPostBinding="false">
${idp.url::http://localhost:8081/auth/realms/demo/protocol/saml}
${employee.url::http://localhost:8081/employee/}