[java-idp-integration-tests] branch main updated: Test SSO using OIDC

Tom Zeller tzeller at dragonacea.biz
Sat Feb 24 16:21:43 UTC 2024


This is an automated email from the git hooks/post-receive script.

tzeller pushed a commit to branch main
in repository java-idp-integration-tests.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-integration-tests.git;a=commit;h=8fc6bea86817814c75c9817ec2856dd2d3ca0a35

The following commit(s) were added to refs/heads/main by this push:
     new 8fc6bea  Test SSO using OIDC
8fc6bea is described below

commit 8fc6bea86817814c75c9817ec2856dd2d3ca0a35
Author: Tom Zeller <tzeller at dragonacea.biz>
AuthorDate: Sat Feb 24 10:21:26 2024 -0600

    Test SSO using OIDC
    
    https://shibboleth.atlassian.net/browse/IDP-2243
---
 src/test/docker/shib-tests-rp/docker-compose.yml   |   2 +
 .../etc/httpd/conf.modules.d/10-auth_openidc.conf  |   6 +-
 .../idp/integration/tests/oidc/OIDCTest.java       | 165 +++++++++++++++++----
 .../idp/integration/tests/oidc/RPContainer.java    |  76 +++++++++-
 .../oidc/shibboleth-idp/metadata/oidc-client.json  |  30 +++-
 5 files changed, 246 insertions(+), 33 deletions(-)

diff --git a/src/test/docker/shib-tests-rp/docker-compose.yml b/src/test/docker/shib-tests-rp/docker-compose.yml
index f593657..1478714 100644
--- a/src/test/docker/shib-tests-rp/docker-compose.yml
+++ b/src/test/docker/shib-tests-rp/docker-compose.yml
@@ -13,6 +13,8 @@ services:
     environment:
       - ServerName=${ServerName:-rp.tests.shibboleth.net}
       - OIDCProviderMetadataURL=${OIDCProviderMetadataURL:-https://idp.tests.shibboleth.net:8443/.well-known/openid-configuration}
+      - OIDCClientID=${OIDCClientID:-test_oidc_rp}
+      - OIDCRedirectURI=${OIDCRedirectURI:-/redirect_uri}
     extra_hosts:
       - "idp.tests.shibboleth.net:host-gateway"
     ports:
diff --git a/src/test/docker/shib-tests-rp/etc/httpd/conf.modules.d/10-auth_openidc.conf b/src/test/docker/shib-tests-rp/etc/httpd/conf.modules.d/10-auth_openidc.conf
index 2365614..8ea77d0 100644
--- a/src/test/docker/shib-tests-rp/etc/httpd/conf.modules.d/10-auth_openidc.conf
+++ b/src/test/docker/shib-tests-rp/etc/httpd/conf.modules.d/10-auth_openidc.conf
@@ -1,15 +1,13 @@
 # Test configuration for mod_auth_openidc RP
 LoadModule auth_openidc_module modules/mod_auth_openidc.so
 
-# OIDCProviderMetadataURL https://idp.tests.shibboleth.net:8443/.well-known/openid-configuration
 OIDCProviderMetadataURL ${OIDCProviderMetadataURL}
-OIDCClientID            test_oidc_rp
+OIDCClientID            ${OIDCClientID}
 OIDCClientSecret        topsecret
 
 # OIDCRedirectURI is a vanity URL that must point to a path protected by this module but must NOT point to any content
 # Relative redirect URI makes testing easier since port is not known until after the container has started.
-# OIDCRedirectURI       https://rp.tests.shibboleth.net:40443/redirect_uri
-OIDCRedirectURI         /redirect_uri
+OIDCRedirectURI         ${OIDCRedirectURI}
 OIDCCryptoPassphrase    secret_passphrase
 OIDCResponseType        id_token
 
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java b/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
index 6ed13cf..3b19d67 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
@@ -22,6 +22,8 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -49,9 +51,9 @@ public class OIDCTest extends BaseIntegrationTest {
     @Nullable
     protected String jwtgenCLI;
 
-    /** RP Docker container. */
-    @Nullable
-    protected RPContainer rp = null;
+    /** RP Docker containers. */
+    @Nonnull
+    protected final List<RPContainer> rps = new ArrayList<>();
 
     @BeforeClass
     public void setUpURLs() throws Exception {
@@ -249,7 +251,7 @@ public class OIDCTest extends BaseIntegrationTest {
      * @throws IOException
      *             if an error occurs
      */
-    protected void registerRP1() throws IOException {
+    protected void enableStaticClientRegistration() throws IOException {
 
         final Path pathToOIDCClientInfoResolversXML = pathToIdPHome
                 .resolve(Paths.get("conf", "oidc-clientinfo-resolvers.xml"));
@@ -272,7 +274,7 @@ public class OIDCTest extends BaseIntegrationTest {
      * @throws IOException
      *             if an error occurs
      */
-    protected void registerRP2() throws IOException {
+    protected void copyStaticClientRegistrations() throws IOException {
 
         final Path pathToOIDCClientJSON = Paths.get("src", "test", "oidc", "shibboleth-idp", "metadata",
                 "oidc-client.json");
@@ -358,35 +360,50 @@ public class OIDCTest extends BaseIntegrationTest {
     /**
      * Start RP.
      * 
-     * @throws ComponentInitializationException if an error occurs
+     * @param hostname
+     *            the hostname
+     * @param clientID
+     *            the client ID
+     * @return
+     * @throws ComponentInitializationException
+     *             if an error occurs
      */
-    protected void startRP() throws ComponentInitializationException {
+    protected RPContainer startRP(@Nonnull final String hostname, @Nonnull final String clientID)
+            throws ComponentInitializationException {
 
-        rp = new RPContainer();
+        final RPContainer rp = new RPContainer();
 
-        rp.setId("rp.tests.shibboleth.net");
+        rps.add(rp);
+
+        rp.setId(hostname);
+
+        rp.setClientID(clientID);
 
         rp.setOPPort(securePort.toString());
 
         rp.initialize();
 
         rp.start();
+
+        return rp;
     }
 
     /**
      * Update client port in their metadata.
      * 
-     * @param port
-     *            the client port
+     * @param oldPort
+     *            the old client port
+     * @param newPort
+     *            the new client port
      * @throws IOException
      *             if an error occurs
      */
-    protected void updateClientPort(@Nonnull final String port) throws IOException {
+    protected void updateClientPort(@Nonnull final String oldPort, @Nonnull final String newPort) throws IOException {
         final Path pathToOIDCClientJSON = pathToIdPHome.resolve(Paths.get("metadata", "oidc-client.json"));
 
         assert pathToOIDCClientJSON.toFile().exists() : "Path to oidc-client.json not found";
 
-        replaceFile(pathToOIDCClientJSON, "40443", port);
+        replaceFile(pathToOIDCClientJSON, oldPort, newPort);
     }
 
     /**
@@ -417,7 +434,7 @@ public class OIDCTest extends BaseIntegrationTest {
      * @throws IOException
      * @throws UnsupportedOperationException
      */
-    protected void getOpenIDConfigurationFromContainer()
+    protected void getOpenIDConfigurationFromContainer(@Nonnull final RPContainer rp)
             throws UnsupportedOperationException, IOException, InterruptedException {
 
         final String baseURL = "https://idp.tests.shibboleth.net:" + securePort;
@@ -515,9 +532,9 @@ public class OIDCTest extends BaseIntegrationTest {
 
         enableOIDCProfiles();
 
-        registerRP1();
+        enableStaticClientRegistration();
 
-        registerRP2();
+        copyStaticClientRegistrations();
 
         enableOIDCDiscovery();
 
@@ -525,9 +542,9 @@ public class OIDCTest extends BaseIntegrationTest {
 
         setUpOPIssuer();
 
-        startRP();
+        final RPContainer rp = startRP("rp.tests.shibboleth.net", "test_oidc_rp");
 
-        updateClientPort(rp.httpsPort.toString());
+        updateClientPort("40443", rp.httpsPort.toString());
 
         startServer();
 
@@ -539,7 +556,7 @@ public class OIDCTest extends BaseIntegrationTest {
 
         getOpenIDConfigurationFromBrowser();
 
-        getOpenIDConfigurationFromContainer();
+        getOpenIDConfigurationFromContainer(rp);
 
         driver.get(rp.getBaseURL() + "/secure");
 
@@ -548,7 +565,7 @@ public class OIDCTest extends BaseIntegrationTest {
         login();
 
         waitForPageURLContains("/secure");
-        
+
         Assert.assertTrue(getPageSource().contains("Secure"));
 
         driver.get(rp.getBaseURL() + "/cgi-bin/printenv");
@@ -558,13 +575,111 @@ public class OIDCTest extends BaseIntegrationTest {
         // TODO more asserts
     }
 
+    @Test(dataProvider = "sauceOnDemandBrowserDataProvider", enabled = false)
+    public void testSSO(@Nullable final BrowserData browserData) throws Exception {
+
+        // Install OIDC OP plugin
+
+        // TODO local install
+        installLocalPlugin("net.shibboleth.oidc.common", "oidc-common-dist-3.0.1.tar.gz");
+        installLocalPlugin("net.shibboleth.idp.plugin.oidc.config", "idp-plugin-oidc-config-dist-2.0.0.tar.gz");
+        installLocalPlugin("net.shibboleth.idp.plugin.oidc.op", "idp-plugin-oidc-op-distribution-4.0.0.tar.gz");
+
+        // TODO remote install
+        final String[] plugins = new String[] { //
+                "net.shibboleth.oidc.common", //
+                "net.shibboleth.idp.plugin.oidc.config", //
+                "net.shibboleth.idp.plugin.oidc.op" };
+        // installPlugins(plugins);
+
+        assertPluginsAreInstalled(plugins);
+
+        buildWAR();
+
+        enableOIDCCredentials();
+
+        enableOIDCAttributes();
+
+        createOIDCCredentials();
+
+        enableOIDCProfiles();
+
+        enableStaticClientRegistration();
+
+        copyStaticClientRegistrations();
+
+        enableOIDCDiscovery();
+
+        setUpIdPAttributes();
+
+        setUpOPIssuer();
+
+        // Start rp.tests.shibboleth.net
+
+        final RPContainer rp = startRP("rp.tests.shibboleth.net", "test_oidc_rp");
+
+        updateClientPort("40443", rp.httpsPort.toString());
+
+        // Start rp1.tests.shibboleth.net
+
+        final RPContainer rp1 = startRP("rp1.tests.shibboleth.net", "test_oidc_rp_1");
+
+        updateClientPort("41443", rp1.httpsPort.toString());
+
+        // Start IdP
+
+        startServer();
+
+        assertPluginsAreOnStatusPage(plugins);
+
+        secureBaseURL = "https://idp.tests.shibboleth.net:" + securePort;
+
+        startSeleniumClient(browserData);
+
+        getOpenIDConfigurationFromBrowser();
+
+        getOpenIDConfigurationFromContainer(rp);
+
+        // Authenticate to rp.tests.shibboleth.net
+
+        driver.get(rp.getBaseURL() + "/cgi-bin/printenv");
+
+        waitForLoginPage();
+
+        login();
+
+        waitForPageURLContains("/cgi-bin/printenv");
+
+        Assert.assertTrue(getPageSource().contains("OIDC_CLAIM_iss=\"https://idp.tests.shibboleth.net\""));
+
+        Assert.assertTrue(getPageSource().contains("OIDC_CLAIM_sub=\"jdoe at example.org\""));
+
+        Assert.assertTrue(getPageSource().contains("SERVER_NAME=\"rp.tests.shibboleth.net\""));
+
+        // SSO to rp1.tests.shibboleth.net
+
+        driver.get(rp1.getBaseURL() + "/cgi-bin/printenv");
+
+        waitForPageURLContains("/cgi-bin/printenv");
+
+        Assert.assertTrue(getPageSource().contains("OIDC_CLAIM_iss=\"https://idp.tests.shibboleth.net\""));
+
+        Assert.assertTrue(getPageSource().contains("OIDC_CLAIM_sub=\"jdoe at example.org\""));
+
+        Assert.assertTrue(getPageSource().contains("SERVER_NAME=\"rp1.tests.shibboleth.net\""));
+
+        // TODO more asserts
+    }
+
     /**
-     * Stop the server.
+     * Stop all RPs.
      */
-    @AfterMethod(dependsOnMethods = { "failTestClass" })
-    public void stopRP() {
-        if (rp != null && rp.isRunning()) {
-            rp.stop();
+    @AfterMethod()
+    public void stopRPs() {
+        for (final RPContainer rp : rps) {
+            if (rp != null && rp.isRunning()) {
+                rp.stop();
+            }
         }
     }
 
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java b/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
index 3baaaea..7f5d9b8 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
@@ -81,7 +81,13 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
 
     /** Port used by the OP. */
     @NonnullAfterInit
-    private String opPort;
+    private String opPort = "443";
+
+    /** RP client ID, defaults to 'test_oidc_rp'. */
+    private String clientID = "test_oidc_rp";
+
+    /** RP redirect URI, defaults to '/redirect_uri'. */
+    private String redirectURI = "/redirect_uri";
 
     /** System property to set path to TLS cert. */
     final static String pathToTLSCertSystemProperty = "tlsCert";
@@ -198,6 +204,10 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
      * 
      * Set OIDCProviderMetadataURL using OP port.
      * 
+     * Set OIDCClientID.
+     * 
+     * Set OIDCRedirectURI.
+     * 
      * Expose ports 80 and 443.
      * 
      * {@inheritDoc}
@@ -247,6 +257,12 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         // Set 'ServerName' environment variable to the id
         container.withEnv("ServerName", getId());
 
+        // Set 'OIDCClientID' environment variable
+        container.withEnv("OIDCClientID", getClientID());
+
+        // Set 'OIDCRedirectURI' environment variable
+        container.withEnv("OIDCRedirectURI", getRedirectURI());
+
         // set OIDCProviderMetadataURL
         final String OIDCProviderMetadataURL = //
                 "https://idp.tests.shibboleth.net:" + opPort + "/.well-known/openid-configuration";
@@ -260,12 +276,16 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
     }
 
     /**
-     * Get base URL of the form "https://rp.tests.shibboleth.net:<port>".
+     * Get base URL of the form "https://<id>:<port>".
+     * 
+     * For example : "https://rp.tests.shibboleth.net:<port>"
+     * 
+     * The host name / FQDN is set via {@link #setId(String)}.
      * 
      * @return base URL
      */
     public String getBaseURL() {
-        return "https://rp.tests.shibboleth.net:" + httpsPort.toString();
+        return "https://" + getId() + ":" + httpsPort.toString();
     }
 
     /**
@@ -283,6 +303,34 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         return logPrefix;
     }
 
+    /**
+     * Get the OIDC client ID.
+     * 
+     * @return client ID
+     */
+    public String getClientID() {
+        return clientID;
+    }
+
+    /**
+     * Get the OIDC redirect URI.
+     * 
+     * @return redirect URI
+     */
+    public String getRedirectURI() {
+        return redirectURI;
+    }
+
+    /**
+     * Set the ID to the FQDN of the RP.
+     * 
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setId(String componentId) {
+        super.setId(componentId);
+    }
+
     /**
      * Set the OP port used to construct the OIDCProviderMetadataURL.
      * 
@@ -294,6 +342,28 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         opPort = port;
     }
 
+    /**
+     * Set the OIDC client ID.
+     * 
+     * @param id
+     *            client ID
+     */
+    public void setClientID(@Nonnull final String id) {
+        Constraint.isNotNull(id, "Client ID cannot be null");
+        clientID = id;
+    }
+
+    /**
+     * Set the OIDC redirect URI.
+     * 
+     * @param uri
+     *            redirect URI
+     */
+    public void setRedirectURI(@Nonnull final String uri) {
+        Constraint.isNotNull(uri, "Redirect URI cannot be null");
+        redirectURI = uri;
+    }
+
     /**
      * Start container and wait for web server to be available.
      * 
diff --git a/src/test/oidc/shibboleth-idp/metadata/oidc-client.json b/src/test/oidc/shibboleth-idp/metadata/oidc-client.json
index 996fd9c..e3ff316 100644
--- a/src/test/oidc/shibboleth-idp/metadata/oidc-client.json
+++ b/src/test/oidc/shibboleth-idp/metadata/oidc-client.json
@@ -1,7 +1,9 @@
 [
   {
     "scope": "openid email",
-    "redirect_uris": [ "https://rp.tests.shibboleth.net:40443/redirect_uri" ],
+    "redirect_uris": [
+      "https://rp.tests.shibboleth.net:40443/redirect_uri"
+    ],
     "client_id": "test_oidc_rp",
     "client_secret": "topsecret",
     "response_types": [
@@ -9,5 +11,31 @@
       "id_token",
       "id_token token"
     ]
+  },
+  {
+    "scope": "openid email",
+    "redirect_uris": [
+      "https://rp1.tests.shibboleth.net:41443/redirect_uri"
+    ],
+    "client_id": "test_oidc_rp_1",
+    "client_secret": "topsecret",
+    "response_types": [
+      "code",
+      "id_token",
+      "id_token token"
+    ]
+  },
+  {
+    "scope": "openid email",
+    "redirect_uris": [
+      "https://rp2.tests.shibboleth.net:42443/redirect_uri"
+    ],
+    "client_id": "test_oidc_rp_2",
+    "client_secret": "topsecret",
+    "response_types": [
+      "code",
+      "id_token",
+      "id_token token"
+    ]
   }
 ]

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list