Rationalising SAML SSO Federation tests
Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/ce2cc78f Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/ce2cc78f Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/ce2cc78f Branch: refs/heads/master Commit: ce2cc78f7429f626e661c56bb78b5441d838f6ee Parents: 04fa2ea Author: Colm O hEigeartaigh <[email protected]> Authored: Thu Nov 3 14:58:25 2016 +0000 Committer: Colm O hEigeartaigh <[email protected]> Committed: Thu Nov 3 14:58:25 2016 +0000 ---------------------------------------------------------------------- systests/federation/samlsso/pom.xml | 8 - .../integrationtests/SAMLSSOFedizTest.java | 254 ------------------- .../cxf/fediz/integrationtests/SAMLSSOTest.java | 89 +++++-- 3 files changed, 73 insertions(+), 278 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/ce2cc78f/systests/federation/samlsso/pom.xml ---------------------------------------------------------------------- diff --git a/systests/federation/samlsso/pom.xml b/systests/federation/samlsso/pom.xml index 1c46c8e..da610a7 100644 --- a/systests/federation/samlsso/pom.xml +++ b/systests/federation/samlsso/pom.xml @@ -180,14 +180,6 @@ <outputDirectory>target/tomcat/rp/webapps/simpleWebapp</outputDirectory> </artifactItem> <artifactItem> - <groupId>org.apache.cxf.fediz.systests.webapps</groupId> - <artifactId>fediz-systests-webapps-simple</artifactId> - <version>${project.version}</version> - <type>war</type> - <overWrite>true</overWrite> - <outputDirectory>target/tomcat/rp/webapps/simpleWebapp2</outputDirectory> - </artifactItem> - <artifactItem> <groupId>org.apache.cxf.fediz</groupId> <artifactId>fediz-idp</artifactId> <version>${project.version}</version> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/ce2cc78f/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOFedizTest.java ---------------------------------------------------------------------- diff --git a/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOFedizTest.java b/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOFedizTest.java deleted file mode 100644 index a9b0762..0000000 --- a/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOFedizTest.java +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.cxf.fediz.integrationtests; - - -import java.io.File; -import java.io.IOException; - -import javax.servlet.ServletException; - -import com.gargoylesoftware.htmlunit.CookieManager; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; - -import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleState; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.startup.Tomcat; -import org.apache.cxf.fediz.core.ClaimTypes; -import org.apache.cxf.fediz.tomcat7.FederationAuthenticator; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; - -/** - * This is a test for federation in the IdP. The RP application is configured to use a home realm of "realm b". The - * client gets redirected to the IdP for "realm a", which in turn redirects to the (Fediz) IdP for "realm b" - * via SAML SSO. The user authenticates + is redirected back to the IdP for "realm a" to get a - * SAML token from the STS + then back to the application. - */ -public class SAMLSSOFedizTest { - - static String idpHttpsPort; - static String idpRealmbHttpsPort; - static String rpHttpsPort; - - private static Tomcat idpServer; - private static Tomcat idpRealmbServer; - private static Tomcat rpServer; - - @BeforeClass - public static void init() throws Exception { - System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); - System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); - System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "info"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "info"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.springframework.webflow", "info"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.springframework.security.web", "info"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.cxf.fediz", "info"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.cxf", "info"); - - idpHttpsPort = System.getProperty("idp.https.port"); - Assert.assertNotNull("Property 'idp.https.port' null", idpHttpsPort); - idpRealmbHttpsPort = System.getProperty("idp.realmb.https.port"); - Assert.assertNotNull("Property 'idp.realmb.https.port' null", idpRealmbHttpsPort); - rpHttpsPort = System.getProperty("rp.https.port"); - Assert.assertNotNull("Property 'rp.https.port' null", rpHttpsPort); - - idpServer = startServer(true, false, idpHttpsPort); - idpRealmbServer = startServer(false, true, idpRealmbHttpsPort); - rpServer = startServer(false, false, rpHttpsPort); - } - - private static Tomcat startServer(boolean idp, boolean realmb, String port) - throws ServletException, LifecycleException, IOException { - Tomcat server = new Tomcat(); - server.setPort(0); - String currentDir = new File(".").getCanonicalPath(); - String baseDir = currentDir + File.separator + "target"; - server.setBaseDir(baseDir); - - if (idp) { - server.getHost().setAppBase("tomcat/idp/webapps"); - } else if (realmb) { - server.getHost().setAppBase("tomcat/idprealmb/webapps"); - } else { - server.getHost().setAppBase("tomcat/rp/webapps"); - } - server.getHost().setAutoDeploy(true); - server.getHost().setDeployOnStartup(true); - - Connector httpsConnector = new Connector(); - httpsConnector.setPort(Integer.parseInt(port)); - httpsConnector.setSecure(true); - httpsConnector.setScheme("https"); - //httpsConnector.setAttribute("keyAlias", keyAlias); - httpsConnector.setAttribute("keystorePass", "tompass"); - httpsConnector.setAttribute("keystoreFile", "test-classes/server.jks"); - httpsConnector.setAttribute("truststorePass", "tompass"); - httpsConnector.setAttribute("truststoreFile", "test-classes/server.jks"); - httpsConnector.setAttribute("clientAuth", "want"); - // httpsConnector.setAttribute("clientAuth", "false"); - httpsConnector.setAttribute("sslProtocol", "TLS"); - httpsConnector.setAttribute("SSLEnabled", true); - - server.getService().addConnector(httpsConnector); - - if (idp) { - File stsWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp-sts"); - server.addWebapp("/fediz-idp-sts", stsWebapp.getAbsolutePath()); - - File idpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp"); - server.addWebapp("/fediz-idp", idpWebapp.getAbsolutePath()); - } else if (realmb) { - File stsWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp-sts-realmb"); - server.addWebapp("/fediz-idp-sts-realmb", stsWebapp.getAbsolutePath()); - - File idpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp-realmb"); - server.addWebapp("/fediz-idp-realmb", idpWebapp.getAbsolutePath()); - } else { - File rpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "simpleWebapp"); - Context cxt = server.addWebapp("/fedizhelloworld3", rpWebapp.getAbsolutePath()); - - FederationAuthenticator fa = new FederationAuthenticator(); - fa.setConfigFile(currentDir + File.separator + "target" + File.separator - + "test-classes" + File.separator + "fediz_config_saml_sso.xml"); - cxt.getPipeline().addValve(fa); - } - - server.start(); - - return server; - } - - @AfterClass - public static void cleanup() { - shutdownServer(idpServer); - shutdownServer(idpRealmbServer); - shutdownServer(rpServer); - } - - private static void shutdownServer(Tomcat server) { - try { - if (server != null && server.getServer() != null - && server.getServer().getState() != LifecycleState.DESTROYED) { - if (server.getServer().getState() != LifecycleState.STOPPED) { - server.stop(); - } - server.destroy(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public String getIdpHttpsPort() { - return idpHttpsPort; - } - - public String getIdpRealmbHttpsPort() { - return idpRealmbHttpsPort; - } - - public String getRpHttpsPort() { - return rpHttpsPort; - } - - public String getServletContextName() { - return "fedizhelloworld"; - } - - @org.junit.Test - public void testSAMLSSO() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/fedizhelloworld3/secure/fedservlet"; - // System.out.println(url); - // Thread.sleep(60 * 2 * 1000); - String user = "ALICE"; // realm b credentials - String password = "ECILA"; - - final String bodyTextContent = - login(url, user, password, getIdpRealmbHttpsPort(), getIdpHttpsPort(), true); - - Assert.assertTrue("Principal not alice", - bodyTextContent.contains("userPrincipal=alice")); - Assert.assertTrue("User " + user + " does not have role Admin", - bodyTextContent.contains("role:Admin=false")); - Assert.assertTrue("User " + user + " does not have role Manager", - bodyTextContent.contains("role:Manager=false")); - Assert.assertTrue("User " + user + " must have role User", - bodyTextContent.contains("role:User=true")); - - String claim = ClaimTypes.FIRSTNAME.toString(); - Assert.assertTrue("User " + user + " claim " + claim + " is not 'Alice'", - bodyTextContent.contains(claim + "=Alice")); - claim = ClaimTypes.LASTNAME.toString(); - Assert.assertTrue("User " + user + " claim " + claim + " is not 'Smith'", - bodyTextContent.contains(claim + "=Smith")); - claim = ClaimTypes.EMAILADDRESS.toString(); - Assert.assertTrue("User " + user + " claim " + claim + " is not '[email protected]'", - bodyTextContent.contains(claim + "[email protected]")); - } - - private static String login(String url, String user, String password, - String idpPort, String rpIdpPort, boolean postBinding) throws IOException { - // - // Access the RP + get redirected to the IdP for "realm a". Then get redirected to the IdP for - // "realm b". - // - final WebClient webClient = new WebClient(); - CookieManager cookieManager = new CookieManager(); - webClient.setCookieManager(cookieManager); - webClient.getOptions().setUseInsecureSSL(true); - webClient.getCredentialsProvider().setCredentials( - new AuthScope("localhost", Integer.parseInt(idpPort)), - new UsernamePasswordCredentials(user, password)); - - webClient.getOptions().setJavaScriptEnabled(false); - HtmlPage idpPage = webClient.getPage(url); - - if (postBinding) { - Assert.assertEquals("IDP SignIn Response Form", idpPage.getTitleText()); - final HtmlForm form = idpPage.getFormByName("samlsigninresponseform"); - final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); - idpPage = button.click(); - } - - Assert.assertEquals("IDP SignIn Response Form", idpPage.getTitleText()); - - // Now redirect back to the RP - final HtmlForm form = idpPage.getFormByName("signinresponseform"); - - final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); - - final HtmlPage rpPage = button.click(); - Assert.assertEquals("WS Federation Systests Examples", rpPage.getTitleText()); - - webClient.close(); - return rpPage.getBody().getTextContent(); - } - - -} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/ce2cc78f/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOTest.java ---------------------------------------------------------------------- diff --git a/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOTest.java b/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOTest.java index 4637be3..0f67fc7 100644 --- a/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOTest.java +++ b/systests/federation/samlsso/src/test/java/org/apache/cxf/fediz/integrationtests/SAMLSSOTest.java @@ -54,20 +54,21 @@ import org.junit.BeforeClass; import org.junit.Test; /** - * This is a test for federation in the IdP. The RP application is configured to use a home realm of "realm b". The - * client gets redirected to the IdP for "realm a", which in turn redirects to the IdP for "realm b", which is a - * SAML SSO IdP. The IdP for "realm a" will convert the signin request to a SAML SSO sign in request. The IdP for - * realm b authenticates the user, who is then redirected back to the IdP for "realm a" to get a SAML token from - * the STS + then back to the application. + * This is a test for federation using SAML SSO in the IdP. The RP application is configured to use a home realm + * which is different to that of the IdP ("realm a"). The IdP for realm "a" then redirects the client to the + * relevant IdP, which is a SAML SSO IdP. Two different third party IdPs are used - a mock SAML SSO IdP, which + * supports both the redirect and POST bindings, as well as the Fediz IdP itself. */ public class SAMLSSOTest { static String idpHttpsPort; static String idpSamlSSOHttpsPort; static String rpHttpsPort; + static String idpRealmbHttpsPort; private static Tomcat idpServer; private static Tomcat idpSamlSSOServer; + private static Tomcat idpRealmbServer; private static Tomcat rpServer; @BeforeClass @@ -85,15 +86,18 @@ public class SAMLSSOTest { Assert.assertNotNull("Property 'idp.https.port' null", idpHttpsPort); idpSamlSSOHttpsPort = System.getProperty("idp.samlsso.https.port"); Assert.assertNotNull("Property 'idp.samlsso.https.port' null", idpSamlSSOHttpsPort); + idpRealmbHttpsPort = System.getProperty("idp.realmb.https.port"); + Assert.assertNotNull("Property 'idp.realmb.https.port' null", idpRealmbHttpsPort); rpHttpsPort = System.getProperty("rp.https.port"); Assert.assertNotNull("Property 'rp.https.port' null", rpHttpsPort); - idpServer = startServer(true, false, idpHttpsPort); - idpSamlSSOServer = startServer(false, true, idpSamlSSOHttpsPort); - rpServer = startServer(false, false, rpHttpsPort); + idpServer = startServer(true, false, false, idpHttpsPort); + idpSamlSSOServer = startServer(false, true, false, idpSamlSSOHttpsPort); + idpRealmbServer = startServer(false, false, true, idpRealmbHttpsPort); + rpServer = startServer(false, false, false, rpHttpsPort); } - private static Tomcat startServer(boolean idp, boolean realmb, String port) + private static Tomcat startServer(boolean idp, boolean samlSSOIdP, boolean realmb, String port) throws ServletException, LifecycleException, IOException { Tomcat server = new Tomcat(); server.setPort(0); @@ -103,8 +107,10 @@ public class SAMLSSOTest { if (idp) { server.getHost().setAppBase("tomcat/idp/webapps"); - } else if (realmb) { + } else if (samlSSOIdP) { server.getHost().setAppBase("tomcat/idpsamlsso/webapps"); + } else if (realmb) { + server.getHost().setAppBase("tomcat/idprealmb/webapps"); } else { server.getHost().setAppBase("tomcat/rp/webapps"); } @@ -133,9 +139,15 @@ public class SAMLSSOTest { File idpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp"); server.addWebapp("/fediz-idp", idpWebapp.getAbsolutePath()); - } else if (realmb) { + } else if (samlSSOIdP) { File idpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "idpsaml"); server.addWebapp("/idp", idpWebapp.getAbsolutePath()); + } else if (realmb) { + File stsWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp-sts-realmb"); + server.addWebapp("/fediz-idp-sts-realmb", stsWebapp.getAbsolutePath()); + + File idpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "fediz-idp-realmb"); + server.addWebapp("/fediz-idp-realmb", idpWebapp.getAbsolutePath()); } else { File rpWebapp = new File(baseDir + File.separator + server.getHost().getAppBase(), "simpleWebapp"); Context cxt = server.addWebapp("/fedizhelloworld", rpWebapp.getAbsolutePath()); @@ -145,9 +157,13 @@ public class SAMLSSOTest { + "test-classes" + File.separator + "fediz_config_saml_sso.xml"); cxt.getPipeline().addValve(fa); - File rpWebapp2 = new File(baseDir + File.separator + server.getHost().getAppBase(), "simpleWebapp2"); + File rpWebapp2 = new File(baseDir + File.separator + server.getHost().getAppBase(), "simpleWebapp"); cxt = server.addWebapp("/fedizhelloworld-post-binding", rpWebapp2.getAbsolutePath()); cxt.getPipeline().addValve(fa); + + File rpWebapp3 = new File(baseDir + File.separator + server.getHost().getAppBase(), "simpleWebapp"); + cxt = server.addWebapp("/fedizhelloworld3", rpWebapp3.getAbsolutePath()); + cxt.getPipeline().addValve(fa); } server.start(); @@ -160,6 +176,7 @@ public class SAMLSSOTest { public static void cleanup() { shutdownServer(idpServer); shutdownServer(idpSamlSSOServer); + shutdownServer(idpRealmbServer); shutdownServer(rpServer); } @@ -189,6 +206,10 @@ public class SAMLSSOTest { return "fedizhelloworld"; } + public String getIdpRealmbHttpsPort() { + return idpRealmbHttpsPort; + } + @org.junit.Test public void testSAMLSSO() throws Exception { String url = "https://localhost:" + getRpHttpsPort() + "/fedizhelloworld/secure/fedservlet"; @@ -284,6 +305,37 @@ public class SAMLSSOTest { webClient.close(); } + @org.junit.Test + public void testSAMLSSOFedizIdP() throws Exception { + String url = "https://localhost:" + getRpHttpsPort() + "/fedizhelloworld3/secure/fedservlet"; + // System.out.println(url); + // Thread.sleep(60 * 2 * 1000); + String user = "ALICE"; // realm b credentials + String password = "ECILA"; + + final String bodyTextContent = + login(url, user, password, getIdpRealmbHttpsPort(), getIdpHttpsPort(), true); + + Assert.assertTrue("Principal not alice", + bodyTextContent.contains("userPrincipal=alice")); + Assert.assertTrue("User " + user + " does not have role Admin", + bodyTextContent.contains("role:Admin=false")); + Assert.assertTrue("User " + user + " does not have role Manager", + bodyTextContent.contains("role:Manager=false")); + Assert.assertTrue("User " + user + " must have role User", + bodyTextContent.contains("role:User=true")); + + String claim = ClaimTypes.FIRSTNAME.toString(); + Assert.assertTrue("User " + user + " claim " + claim + " is not 'Alice'", + bodyTextContent.contains(claim + "=Alice")); + claim = ClaimTypes.LASTNAME.toString(); + Assert.assertTrue("User " + user + " claim " + claim + " is not 'Smith'", + bodyTextContent.contains(claim + "=Smith")); + claim = ClaimTypes.EMAILADDRESS.toString(); + Assert.assertTrue("User " + user + " claim " + claim + " is not '[email protected]'", + bodyTextContent.contains(claim + "[email protected]")); + } + private static String login(String url, String user, String password, String idpPort, String rpIdpPort, boolean postBinding) throws IOException { // @@ -302,10 +354,15 @@ public class SAMLSSOTest { HtmlPage idpPage = webClient.getPage(url); if (postBinding) { - Assert.assertEquals("SAML IDP Response Form", idpPage.getTitleText()); - final HtmlForm form = idpPage.getFormByName("signinresponseform"); - final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); - idpPage = button.click(); + Assert.assertTrue("SAML IDP Response Form".equals(idpPage.getTitleText()) + || "IDP SignIn Response Form".equals(idpPage.getTitleText())); + for (HtmlForm form : idpPage.getForms()) { + String name = form.getAttributeNS(null, "name"); + if ("signinresponseform".equals(name) || "samlsigninresponseform".equals(name)) { + final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); + idpPage = button.click(); + } + } } Assert.assertEquals("IDP SignIn Response Form", idpPage.getTitleText());
