From a167960af54b929f5fb932d5a2cefb7ea27ebce0 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:37:06 -0600 Subject: [PATCH 01/33] IDP-1041 remove expirychecker dateFormat --- README.md | 4 ---- modules/expirychecker/src/Auth/Process/ExpiryDate.php | 5 ----- 2 files changed, 9 deletions(-) diff --git a/README.md b/README.md index 8e768d1..32f1fe1 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,6 @@ Example (in `metadata/saml20-idp-hosted.php`): // Optional: 'warnDaysBefore' => 14, 'originalUrlParam' => 'originalurl', - 'dateFormat' => 'm.d.Y', // Use PHP's date syntax. 'loggerClass' => '\\Sil\\Psr3Adapters\\Psr3SamlLogger', ], @@ -184,9 +183,6 @@ returned when the user successfully authenticates. The `warnDaysBefore` parameter should be an integer representing how many days before the expiry date the "about to expire" warning will be shown to the user. -The `dateFormat` parameter specifies how you want the date to be formatted, -using PHP `date()` syntax. See . - The `loggerClass` parameter specifies the name of a PSR-3 compatible class that can be autoloaded, to use as the logger within ExpiryDate. diff --git a/modules/expirychecker/src/Auth/Process/ExpiryDate.php b/modules/expirychecker/src/Auth/Process/ExpiryDate.php index 3efd9e6..4a91002 100644 --- a/modules/expirychecker/src/Auth/Process/ExpiryDate.php +++ b/modules/expirychecker/src/Auth/Process/ExpiryDate.php @@ -32,7 +32,6 @@ class ExpiryDate extends ProcessingFilter private string|null $accountNameAttr = null; private string $employeeIdAttr = 'employeeNumber'; private string|null $expiryDateAttr = null; - private string $dateFormat = 'Y-m-d'; protected LoggerInterface $logger; @@ -70,10 +69,6 @@ public function __construct(array $config, mixed $reserved) Validator::STRING, Validator::NOT_EMPTY, ], - 'dateFormat' => [ - Validator::STRING, - Validator::NOT_EMPTY, - ], ]); } From 592194e2afaf2f45223e6da9591a3e2ec5136b6b Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:35:17 -0600 Subject: [PATCH 02/33] update docs for changes made during SSP 2 upgrade --- README.md | 85 +++++++++++++++++---------------------- docs/editing_authprocs.md | 4 -- docs/the_hub.md | 9 +---- local.env.dist | 1 - 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 8e768d1..8c751dd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# ssp-base -Base image for simpleSAMLphp +# ssp-base + +Base image for SimpleSAMLphp IdP and Hub with custom modules Docker image: [silintl/ssp-base](https://hub.docker.com/r/silintl/ssp-base/) @@ -9,8 +10,6 @@ must be installed. [Make](https://www.gnu.org/software/make) is optional but simplifies the build process. -[PHP](https://www.php.net) and [Composer](https://getcomposer.org) are optional, but at a minimum you need COMPOSER_CACHE_DIR set to a local directory for storing the PHP dependency cache. This must be exported in your local development environment, not in the Docker container environment. For example, in your `~/.bashrc`, include `export COMPOSER_CACHE_DIR="$HOME/.composer"` and create an empty directory at `~/.composer`. - ## Configuration By default, configuration is read from environment variables. These are documented in the `local.env.dist` file. Optionally, you can define configuration in AWS AppConfig. @@ -35,10 +34,10 @@ will overwrite variables set in the execution environment. 1. `cp local.env.dist local.env` within project root and make adjustments as needed. 2. `cp local.broker.env.dist local.broker.env` within project root and make adjustments as needed. -3. Add your github token to the `COMPOSER_AUTH` variable in the `local.env` file. +3. Add your GitHub [personal access token](https://github.com/settings/tokens?type=beta) to the `COMPOSER_AUTH` variable in the `local.env` file. 4. Create `localhost` aliases for `ssp-hub.local`, `ssp-idp1.local`, `ssp-idp2.local`, `ssp-idp3.local`, `ssp-sp1.local`, `ssp-sp2.local`, and `ssp-sp3.local`. This is typically done in `/etc/hosts`. _Example line: `127.0.0.1 ssp-hub.local ssp-idp1.local ssp-idp2.local ssp-idp3.local ssp-sp1.local ssp-sp2.local ssp-sp3.local`_ -4. `make` or `docker compose up -d` within the project root. -5. Visit http://ssp-hub.local to see SimpleSAMLphp +5. Run `make test` within the project root. +6. Visit http://ssp-hub.local to see SimpleSAMLphp _Note:_ there is an unresolved problem that requires a change to BASE_URL_PATH for ssp-idp1.local in docker-compose.yml due to a requirement in silauth that it be a full URL. For automated testing, it must not have a port number, but for manual testing it needs the port number. @@ -93,7 +92,7 @@ docker composer up -d ssp-hub.local - Port: 80 - Debugger: Xdebug - Check use path mappings and add map from project root to `/data` - + 13. Hit `Apply` and `OK` 14. Click on `Run` and then `Debug 'Debug on Docker'` @@ -168,7 +167,7 @@ Example (in `metadata/saml20-idp-hosted.php`): 'dateFormat' => 'm.d.Y', // Use PHP's date syntax. 'loggerClass' => '\\Sil\\Psr3Adapters\\Psr3SamlLogger', ], - + // ... ], @@ -181,12 +180,18 @@ the user's expiry date, which must be formated as YYYYMMDDHHMMSSZ (e.g. `20111011235959Z`). Those two attributes need to be part of the attribute set returned when the user successfully authenticates. +The `passwordChangeUrl` parameter contains the URL of the password manager. A +link to that URL may be presented to the user as a convenience for updating +their password. + The `warnDaysBefore` parameter should be an integer representing how many days before the expiry date the "about to expire" warning will be shown to the user. The `dateFormat` parameter specifies how you want the date to be formatted, using PHP `date()` syntax. See . +The `originalUrlParam` parameter is not used. + The `loggerClass` parameter specifies the name of a PSR-3 compatible class that can be autoloaded, to use as the logger within ExpiryDate. @@ -200,46 +205,31 @@ they did on those two modules. Material Design theme for use with SimpleSAMLphp -#### Installation - -``` -composer.phar require silinternational/simplesamlphp-module-material:dev-master -``` - #### Configuration -Update `/simplesamlphp/config/config.php`: - -``` -'theme.use' => 'material:material' -``` - -This project sets this as the default value in the provided config file. +No configuration is necessary. The `theme.use` config option is pre-configured to `material:material`. +Optional configuration is described below. ##### Google reCAPTCHA -If a site key has been provided in `$this->data['recaptcha.siteKey']`, the +If a site key has been provided in the `RECAPTCHA_SITE_KEY` environment variable, the username/password page may require the user prove his/her humanity. ##### Branding -Update `/simplesamlphp/config/config.php`: +Set the `THEME_COLOR_SCHEME` environment variable using one of the following values: ``` -'theme.color-scheme' => ['indigo-purple'|'blue_grey-teal'|'red-teal'|'orange-light_blue'|'brown-orange'|'teal-blue'] +'indigo-purple', 'blue_grey-teal', 'red-teal', 'orange-light_blue', 'brown-orange', 'teal-blue' ``` +The default is `indigo-purple`. + The login page looks for `/simplesamlphp/public/logo.png` which is **NOT** provided by default. ##### Analytics -Update `/simplesamlphp/config/config.php`: - -``` -'analytics.trackingId' => 'UA-some-unique-id-for-your-site' -``` - -This project provides a convenience by loading this config with whatever is in the environment variable `ANALYTICS_ID`._ +Set the `ANALYTICS_ID` environment variable to contain your Google Analytics 4 tag ID. ##### Announcements @@ -259,11 +249,12 @@ If provided, an alert will be shown to the user filled with the content of that #### i18n support -Translations are categorized by page in definition files located in the `dictionaries` directory. +Translations are categorized by page in definition files located in the `modules/material/locales` directory. -Localization is affected by the configuration setting `language.available`. Only language codes found in this property will be utilized. -For example, if a translation is provided in Afrikaans for this module, the configuration must be adjusted to make 'af' an available -language. If that's not done, the translation function will not utilize the translations even if provided. +Localization is affected by the configuration setting `language.available`. Only language codes found in this property +will be utilized. For example, if a translation is provided in Afrikaans for this module, the configuration must be +adjusted to make 'af' an available language. If that's not done, the translation function will not utilize the +translations even if provided. ### Multi-Factor Authentication (MFA) simpleSAMLphp Module A simpleSAMLphp module for prompting the user for MFA credentials (such as a @@ -285,9 +276,9 @@ Example (for `metadata/saml20-idp-hosted.php`): use Sil\PhpEnv\Env; use Sil\Psr3Adapters\Psr3SamlLogger; - + // ... - + 'authproc' => [ 10 => [ // Required: @@ -303,7 +294,7 @@ Example (for `metadata/saml20-idp-hosted.php`): // Optional: 'loggerClass' => Psr3SamlLogger::class, ], - + // ... ], @@ -312,7 +303,7 @@ the user's Employee ID stored in it. In certain situations, this may be displayed to the user, as well as being used in log messages. The `loggerClass` parameter specifies the name of a PSR-3 compatible class that -can be autoloaded, to use as the logger within ExpiryDate. +can be autoloaded, to use as the logger within the module. The `mfaSetupUrl` parameter is for the URL of where to send the user if they want/need to set up MFA. @@ -327,12 +318,12 @@ Based on... implemented as AuthProcs, - implementing my solution as an AuthProc and having a number of tests that all confirm that it is working as desired, and -- a discussion in the SimpleSAMLphp mailing list about this: +- a discussion in the SimpleSAMLphp mailing list about this: https://groups.google.com/d/msg/simplesamlphp/ocQols0NCZ8/RL_WAcryBwAJ ... it seems sufficiently safe to implement MFA using a simpleSAMLphp AuthProc. -For more of the details, please see this Stack Overflow Q&A: +For more of the details, please see this Stack Overflow Q&A: https://stackoverflow.com/q/46566014/3813891 #### Acknowledgements @@ -361,9 +352,9 @@ Example (for `metadata/saml20-idp-hosted.php`): use Sil\PhpEnv\Env; use Sil\Psr3Adapters\Psr3SamlLogger; - + // ... - + 'authproc' => [ 10 => [ // Required: @@ -375,7 +366,7 @@ Example (for `metadata/saml20-idp-hosted.php`): // Optional: 'loggerClass' => Psr3SamlLogger::class, ], - + // ... ], @@ -397,8 +388,6 @@ SimpleSAMLphp auth module implementing custom business logic: - rate limiting - status endpoint -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/silinternational/simplesamlphp-module-silauth/develop/LICENSE) - #### Database Migrations To create another database migration file, run the following (replacing `YourMigrationName` with whatever you want the migration to be named, using @@ -466,7 +455,7 @@ load balancer) in the TRUSTED_IP_ADDRESSES environment variable (see `local.env.dist`). #### Status Check -To check the status of the website, you can access this URL: +To check the status of the website, you can access this URL: `https://(your domain name)/module.php/silauth/status.php` ### SilDisco module for SAML Discovery diff --git a/docs/editing_authprocs.md b/docs/editing_authprocs.md index 88013fa..2002dcc 100644 --- a/docs/editing_authprocs.md +++ b/docs/editing_authprocs.md @@ -1,9 +1,5 @@ The sildisco module includes a few Auth Procs that can be called from the `config.php` file or **SP or IdP metadata**. -### AttributeMap.php - -Copies (rather than replaces) attributes according to an attribute map. - ### TagGroup.php Grabs the values of the `urn:oid:2.5.4.31` (member of) attribute and prepends them with `idp||`. diff --git a/docs/the_hub.md b/docs/the_hub.md index e9bab58..924f34f 100644 --- a/docs/the_hub.md +++ b/docs/the_hub.md @@ -1,10 +1,5 @@ The hub will need its certs, `config.php` and `authsources.php` files as a normal simplesamlphp installation. Examples of these can be found in the `./development/hub` folder. (Note the `discoURL` entry in the `authsources.php` file.) -Other files it will need are as follows ... -* The files in the `./src` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/src` -* The files in the `./public` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/public` -* The `./sspoverrides/www_saml2_idp/SSOService.php` file will need overwrite the same out-of-the-box file in `/data/vendor/simplesamlphp/simplesamlphp/public/saml2/idp/` - ### Metadata files The hub should use the `saml20-*-remote.php` files from [ssp-base](https://github.com/silinternational/ssp-base) in `/data/vendor/simplesamlphp/simplesamlphp/metadata/`. These pull in metadata from all the files named `idp-*.php` and `sp-*.php` respectively, including those in sub-folders. @@ -22,12 +17,12 @@ It is also used by the `TagGroup.php` Auth Proc to convert group names into the `idp||`. ##### SPList -In order to limit access to an IdP to only certain SP's, add an `'SPList'` array entry to the metadata for the IdP. The values of this array should match the `entity_id` values from the `sp-remote.php` metadata. +In order to limit access to an IdP to only certain SP's, add an `'SPList'` array entry to the metadata for the IdP. The values of this array should match the `entityid` values from the `sp-remote.php` metadata. ##### excludeByDefault If you want to require SP's to list a certain IdP in their IDPList entry in order to be able to access it, add `excludeByDefault => true` to that IdP's metadata. ### Forced IdP discovery -The `.../src/IdP/SAML2.php` file ensures that if an SP is allowed to access more than one IdP, then the user will be forced back to the IdP discovery page, even if they are already authenticated through one of those IdP's. +The `dockerbuild/ssp-overrides/sp-php.patch` file ensures that if an SP is allowed to access more than one IdP, then the user will be forced back to the IdP discovery page, even if they are already authenticated through one of those IdP's. The reason for this is to ensure that the user has a chance to decide which of their identities is used for that SP. diff --git a/local.env.dist b/local.env.dist index a3a695e..47d955d 100644 --- a/local.env.dist +++ b/local.env.dist @@ -10,7 +10,6 @@ ANALYTICS_ID= BASE_URL_PATH= COMPOSER_ALLOW_SUPERUSER=1 COMPOSER_AUTH={"github-oauth":{"github.com":"token-here"}} -COMPOSER_CACHE_DIR=/composer HUB_MODE=false ENABLE_DEBUG= From 7bb935a06545a4017ee3d2e6eb1ed5dc682d8f50 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:54:39 -0600 Subject: [PATCH 03/33] minor edit in i18n section [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c751dd..4fb3d3a 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ If provided, an alert will be shown to the user filled with the content of that #### i18n support -Translations are categorized by page in definition files located in the `modules/material/locales` directory. +Translations are in files located in the `modules/material/locales` directory. Localization is affected by the configuration setting `language.available`. Only language codes found in this property will be utilized. For example, if a translation is provided in Afrikaans for this module, the configuration must be From d64ceaa00041f9c45719481cad54c961ba7f54bf Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 15:09:28 -0600 Subject: [PATCH 04/33] remove originalUrlParam --- README.md | 1 - .../src/Auth/Process/ExpiryDate.php | 7 ---- modules/expirychecker/src/Utilities.php | 38 ------------------- 3 files changed, 46 deletions(-) diff --git a/README.md b/README.md index 32f1fe1..2571e28 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,6 @@ Example (in `metadata/saml20-idp-hosted.php`): // Optional: 'warnDaysBefore' => 14, - 'originalUrlParam' => 'originalurl', 'loggerClass' => '\\Sil\\Psr3Adapters\\Psr3SamlLogger', ], diff --git a/modules/expirychecker/src/Auth/Process/ExpiryDate.php b/modules/expirychecker/src/Auth/Process/ExpiryDate.php index 4a91002..93f88a9 100644 --- a/modules/expirychecker/src/Auth/Process/ExpiryDate.php +++ b/modules/expirychecker/src/Auth/Process/ExpiryDate.php @@ -27,7 +27,6 @@ class ExpiryDate extends ProcessingFilter const SESSION_TYPE = 'expirychecker'; private int $warnDaysBefore = 14; - private string $originalUrlParam = 'originalurl'; private string|null $passwordChangeUrl = null; private string|null $accountNameAttr = null; private string $employeeIdAttr = 'employeeNumber'; @@ -53,10 +52,6 @@ public function __construct(array $config, mixed $reserved) 'warnDaysBefore' => [ Validator::INT, ], - 'originalUrlParam' => [ - Validator::STRING, - Validator::NOT_EMPTY, - ], 'passwordChangeUrl' => [ Validator::STRING, Validator::NOT_EMPTY, @@ -354,7 +349,6 @@ public function redirectToExpiredPage(array &$state, string $accountName, int $e /* Save state and redirect. */ $state['passwordChangeUrl'] = $this->passwordChangeUrl; - $state['originalUrlParam'] = $this->originalUrlParam; $id = State::saveState($state, 'expirychecker:expired'); $url = Module::getModuleURL('expirychecker/expired.php'); @@ -389,7 +383,6 @@ protected function redirectToWarningPage(array &$state, string $accountName, int /* Save state and redirect. */ $state['passwordChangeUrl'] = $this->passwordChangeUrl; - $state['originalUrlParam'] = $this->originalUrlParam; $id = State::saveState($state, 'expirychecker:about2expire'); $url = Module::getModuleURL('expirychecker/about2expire.php'); diff --git a/modules/expirychecker/src/Utilities.php b/modules/expirychecker/src/Utilities.php index 871d388..d013ee4 100644 --- a/modules/expirychecker/src/Utilities.php +++ b/modules/expirychecker/src/Utilities.php @@ -13,7 +13,6 @@ class Utilities */ public static function getUrlDomain(string $in_url, string $start_marker = '//', string $end_marker = '/'): string { - $sm_len = strlen($start_marker); $em_len = strlen($end_marker); $start_pos = strpos($in_url, $start_marker); @@ -47,43 +46,6 @@ public static function haveSameDomain( return 0; } - /** - * Expects four strings for ... - * - the url for changing the user's password, - * - the parameter label for the original url the user was headed to - * - the original url the user was headed to - * - the StateId parameter to add to the end of the new version of the url - * Returns a string with special symbols urlencoded and then also encoded - * for apex to use. If the domains of the change password url and the - * original url are different, it appends the StateId to the output. - */ - public static function convertOriginalUrl( - string $passwordChangeUrl, - string $originalUrlParam, - string $originalUrl, - string $stateId - ): string { - $sameDomain = self::haveSameDomain($passwordChangeUrl, - '//', '/', $originalUrl, '//', '/'); - $original = $originalUrlParam . ":" . urlencode($originalUrl); - // make changes that insite/apex needs in url - $original = str_replace('%3A', '*COLON*', $original); - $original = str_replace('%2C', '*COMMA*', $original); - $original = str_replace('%26', '*AMPER*', $original); - - // if it already has a ?, then give it a & - // otherwise give it a ? ... - // and then the StateId param - if (!$sameDomain) { - if (strpos($original, '%3F') !== false) { - $original = $original . "*AMPER*" . $stateId; - } else { - $original = $original . '%3F' . $stateId; - } - } - return $original; - } - /** * If the $relayState begins with "http", returns it. * Otherwise, returns empty string. From be9865b77f4a125532f8c07c41a7fa065464de75 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 15:11:48 -0600 Subject: [PATCH 05/33] remove excludeByDefault --- docs/the_hub.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/the_hub.md b/docs/the_hub.md index e9bab58..171d810 100644 --- a/docs/the_hub.md +++ b/docs/the_hub.md @@ -24,9 +24,6 @@ It is also used by the `TagGroup.php` Auth Proc to convert group names into the ##### SPList In order to limit access to an IdP to only certain SP's, add an `'SPList'` array entry to the metadata for the IdP. The values of this array should match the `entity_id` values from the `sp-remote.php` metadata. -##### excludeByDefault -If you want to require SP's to list a certain IdP in their IDPList entry in order to be able to access it, add `excludeByDefault => true` to that IdP's metadata. - ### Forced IdP discovery The `.../src/IdP/SAML2.php` file ensures that if an SP is allowed to access more than one IdP, then the user will be forced back to the IdP discovery page, even if they are already authenticated through one of those IdP's. From b515714ad9d8690a73b61f006474106ca6ce59dd Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:15:21 -0600 Subject: [PATCH 06/33] get IdP display name from metadata, not config --- .../idp-local/metadata/saml20-idp-hosted.php | 1 + .../idp2-local/metadata/saml20-idp-hosted.php | 1 + .../idp3-local/metadata/saml20-idp-hosted.php | 1 + docker-compose.yml | 10 --------- dockerbuild/config/config.php | 22 +++++-------------- local.env.dist | 1 - modules/mfa/public/new-backup-codes.php | 2 +- modules/mfa/public/prompt-for-mfa.php | 2 +- modules/silauth/public/loginuserpass.php | 2 +- 9 files changed, 11 insertions(+), 31 deletions(-) diff --git a/development/idp-local/metadata/saml20-idp-hosted.php b/development/idp-local/metadata/saml20-idp-hosted.php index 796feea..b59174a 100644 --- a/development/idp-local/metadata/saml20-idp-hosted.php +++ b/development/idp-local/metadata/saml20-idp-hosted.php @@ -13,6 +13,7 @@ $metadata['http://ssp-idp1.local:8085'] = [ 'entityid' => 'http://ssp-idp1.local:8085', + 'name' => ['en' => 'IDP 1'], /* * The hostname of the server (VHOST) that will use this SAML entity. diff --git a/development/idp2-local/metadata/saml20-idp-hosted.php b/development/idp2-local/metadata/saml20-idp-hosted.php index 724dce3..60759f3 100644 --- a/development/idp2-local/metadata/saml20-idp-hosted.php +++ b/development/idp2-local/metadata/saml20-idp-hosted.php @@ -7,6 +7,7 @@ $metadata['http://ssp-idp2.local:8086'] = [ 'entityid' => 'http://ssp-idp2.local:8086', + 'name' => ['en' => 'IDP 2'], /* * The hostname of the server (VHOST) that will use this SAML entity. diff --git a/development/idp3-local/metadata/saml20-idp-hosted.php b/development/idp3-local/metadata/saml20-idp-hosted.php index 2630be2..3e684bd 100644 --- a/development/idp3-local/metadata/saml20-idp-hosted.php +++ b/development/idp3-local/metadata/saml20-idp-hosted.php @@ -7,6 +7,7 @@ $metadata['http://ssp-idp3.local:8087'] = [ 'entityid' => 'http://ssp-idp3.local:8087', + 'name' => ['en' => 'IDP 3'], /* * The hostname of the server (VHOST) that will use this SAML entity. diff --git a/docker-compose.yml b/docker-compose.yml index 05bca64..becdb44 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,6 @@ services: PROFILE_URL_FOR_TESTS: http://pwmanager.local/module.php/core/authenticate.php?as=ssp-hub ADMIN_PASS: b SECRET_SALT: abc123 - IDP_NAME: x volumes: - ./dockerbuild/run-integration-tests.sh:/data/run-integration-tests.sh - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -111,7 +110,6 @@ services: environment: ADMIN_PASS: "abc123" SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJ" - IDP_NAME: "Hub" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "orange-light_blue" @@ -162,7 +160,6 @@ services: environment: ADMIN_PASS: "a" SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJ" - IDP_NAME: "IDP 1" IDP_DOMAIN_NAME: "mfaidp" ID_BROKER_ACCESS_TOKEN: "dummy" ID_BROKER_ASSERT_VALID_IP: "false" @@ -217,7 +214,6 @@ services: environment: ADMIN_PASS: "b" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJ" - IDP_NAME: "IDP 2" IDP_DOMAIN_NAME: "ssp-idp2.local" ID_BROKER_ACCESS_TOKEN: "test-cli-abc123" ID_BROKER_ASSERT_VALID_IP: "true" @@ -261,7 +257,6 @@ services: SECRET_SALT: "h57fjem34fh*nsJFGNjweJ" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" - IDP_NAME: "IdP3" THEME_COLOR_SCHEME: "orange-light_blue" ssp-sp1.local: @@ -283,7 +278,6 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp1" - IDP_NAME: "NA" SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJz1" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -306,7 +300,6 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp2" - IDP_NAME: "NA" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJz2" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -331,7 +324,6 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp3 - IDP_NAME: "NA" SECRET_SALT: h57fjemb&dn^nsJFGNjweJz3 SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -352,7 +344,6 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp1 - IDP_NAME: THIS VARIABLE IS REQUIRED BUT PROBABLY NOT USED SECRET_SALT: NOT-a-secret-k49fjfkw73hjf9t87wjiw SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -369,7 +360,6 @@ services: env_file: - ./local.broker.env environment: - IDP_NAME: "idp" MYSQL_HOST: "brokerDb" MYSQL_DATABASE: "broker" MYSQL_USER: "user" diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index db551f8..946e354 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -29,7 +29,6 @@ // Required to be defined in environment variables $ADMIN_PASS = Env::requireEnv('ADMIN_PASS'); $SECRET_SALT = Env::requireEnv('SECRET_SALT'); - $IDP_NAME = Env::requireEnv('IDP_NAME'); } catch (EnvVarNotFoundException $e) { // Return error response code/message to HTTP request. @@ -45,7 +44,6 @@ } // Defaults provided if not defined in environment -$IDP_DISPLAY_NAME = Env::get('IDP_DISPLAY_NAME', $IDP_NAME); $BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); $ADMIN_EMAIL = Env::get('ADMIN_EMAIL', 'na@example.org'); $ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); @@ -78,22 +76,12 @@ /* * Whether this instance should act as a hub/proxy/bridge using sildisco */ - 'hubmode' => $HUB_MODE, + 'hubmode' => $HUB_MODE, - /* - * Name of this IdP - */ - 'idp_name' => $IDP_NAME, - - /* - * Name of this IdP to display to the user - */ - 'idp_display_name' => $IDP_DISPLAY_NAME, - - /* - * The tracking Id for Google Analytics or some other similar service - */ - 'analytics.trackingId' => $ANALYTICS_ID, + /* + * The tracking Id for Google Analytics or some other similar service + */ + 'analytics.trackingId' => $ANALYTICS_ID, 'passwordChangeUrl' => $PASSWORD_CHANGE_URL, 'passwordForgotUrl' => $PASSWORD_FORGOT_URL, diff --git a/local.env.dist b/local.env.dist index a3a695e..db9d59d 100644 --- a/local.env.dist +++ b/local.env.dist @@ -1,6 +1,5 @@ # These are Required ADMIN_PASS= -IDP_NAME= SECRET_SALT= # These are Optional diff --git a/modules/mfa/public/new-backup-codes.php b/modules/mfa/public/new-backup-codes.php index 67e61fe..539604f 100644 --- a/modules/mfa/public/new-backup-codes.php +++ b/modules/mfa/public/new-backup-codes.php @@ -36,7 +36,7 @@ $t = new Template($globalConfig, 'mfa:new-backup-codes'); $t->data['mfa_setup_url'] = $state['mfaSetupUrl']; $t->data['new_backup_codes'] = $state['newBackupCodes'] ?? []; -$t->data['idp_name'] = $globalConfig->getString('idp_display_name'); +$t->data['idp_name'] = $t->getEntityDisplayName($state['IdPMetadata']); $t->data['codes_for_download'] = urlencode( $t->data['idp_name'] . "\r\n" . join("\r\n", $t->data['new_backup_codes']) ); diff --git a/modules/mfa/public/prompt-for-mfa.php b/modules/mfa/public/prompt-for-mfa.php index f3cde9a..f3b05bf 100644 --- a/modules/mfa/public/prompt-for-mfa.php +++ b/modules/mfa/public/prompt-for-mfa.php @@ -125,7 +125,7 @@ $t->data['browser_js_path'] = '/module.php/mfa/simplewebauthn/browser.js?v=' . $browserJsHash; $t->data['manager_email'] = $state['managerEmail']; $t->data['other_options'] = $otherOptions; -$t->data['idp_name'] = $globalConfig->getString('idp_display_name'); +$t->data['idp_name'] = $t->getEntityDisplayName($state['IdPMetadata']); $t->send(); $logger->info(json_encode([ diff --git a/modules/silauth/public/loginuserpass.php b/modules/silauth/public/loginuserpass.php index 12fc066..6192b8c 100644 --- a/modules/silauth/public/loginuserpass.php +++ b/modules/silauth/public/loginuserpass.php @@ -88,7 +88,7 @@ $t->data['profile_url'] = $state['templateData']['profileUrl'] ?? ''; $t->data['help_center_url'] = $state['templateData']['helpCenterUrl'] ?? ''; $t->data['announcement'] = AnnouncementUtils::getAnnouncement(); -$t->data['idp_name'] = $globalConfig->getString('idp_display_name'); +$t->data['idp_name'] = $t->getEntityDisplayName($state['IdPMetadata']); $t->data['password_forgot_url'] = $globalConfig->getOptionalString('passwordForgotUrl', ''); /* For simplicity's sake, don't bother telling this Request to trust any IP From 67fa338f6f94b72aec601b8f95b5b8d1459cbdf4 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:45:15 -0600 Subject: [PATCH 07/33] change simplesamlphp-module-material references to ssp-base --- dockerbuild/config/config.php | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index db551f8..1a1b784 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -54,7 +54,7 @@ $LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); $LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); -// Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding +// Options: https://github.com/silinternational/ssp-base/blob/main/README.md#branding $THEME_COLOR_SCHEME = Env::get('THEME_COLOR_SCHEME', null); $SECURE_COOKIE = Env::get('SECURE_COOKIE', true); diff --git a/package-lock.json b/package-lock.json index e8abf91..f030bee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,10 @@ { - "name": "simplesamlphp-module-material", + "name": "ssp-base", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "simplesamlphp-module-material", + "name": "ssp-base", "dependencies": { "@simplewebauthn/browser": "^4.1.0" } diff --git a/package.json b/package.json index aca8b16..d3856ad 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "simplesamlphp-module-material", + "name": "ssp-base", "dependencies": { "@simplewebauthn/browser": "^4.1.0" } From 04b84cddb2829f36d737af4803afa041d9bf33e0 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:49:02 -0600 Subject: [PATCH 08/33] move theme.color-scheme nearer the other theme parameters [skip ci] --- dockerbuild/config/config.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index 1a1b784..d5c189f 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -981,6 +981,11 @@ */ 'theme.controller' => MaterialController::class, + /* + * color scheme to use for the material theme + */ + 'theme.color-scheme' => $THEME_COLOR_SCHEME, + /* * Templating options * @@ -1043,12 +1048,6 @@ */ //'frontpage.redirect' => 'https://example.com/', - /* - * color scheme to use for the material theme - * Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding - */ - 'theme.color-scheme' => $THEME_COLOR_SCHEME, - /********************* | DISCOVERY SERVICE | *********************/ From 1ca2826ab7f94ab52b585296efddef94261dc393 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:53:47 -0600 Subject: [PATCH 09/33] remove SAML20_IDP_ENABLE --- dockerbuild/config/config.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index 946e354..7f3812b 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -63,7 +63,6 @@ $MYSQL_USER = Env::get('MYSQL_USER', ''); $MYSQL_PASSWORD = Env::get('MYSQL_PASSWORD', ''); -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); $HUB_MODE = Env::get('HUB_MODE', false); $ANALYTICS_ID = Env::get('ANALYTICS_ID', null); $PASSWORD_CHANGE_URL = Env::get('PASSWORD_CHANGE_URL'); @@ -616,7 +615,7 @@ * one of the functionalities below, but in some cases you could run multiple functionalities. * In example when you are setting up a federation bridge. */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, + 'enable.saml20-idp' => true, 'enable.adfs-idp' => false, From bae2ea8816ff228d4e9d2dc2cb6093b9da035bc0 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:58:57 -0600 Subject: [PATCH 10/33] remove SESSION_DURATION --- dockerbuild/config/config.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index 7f3812b..732450c 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -56,7 +56,6 @@ $THEME_COLOR_SCHEME = Env::get('THEME_COLOR_SCHEME', null); $SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', (60 * 60 * 10))); // 10 hours. $SESSION_STORE_TYPE = Env::get('SESSION_STORE_TYPE', 'phpsession'); $MYSQL_HOST = Env::get('MYSQL_HOST', ''); $MYSQL_DATABASE = Env::get('MYSQL_DATABASE', ''); @@ -658,19 +657,19 @@ * This value is the duration of the session in seconds. Make sure that the time duration of * cookies both at the SP and the IdP exceeds this duration. */ - 'session.duration' => $SESSION_DURATION, + 'session.duration' => (60 * 60 * 10), // 10 hours /* * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for * login and logout requests, this option will control the maximum time these operations can take. * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. */ - 'session.datastore.timeout' => $SESSION_DURATION, + 'session.datastore.timeout' => (60 * 60 * 10), // 10 hours /* * Sets the duration, in seconds, auth state should be stored. */ - 'session.state.timeout' => $SESSION_DURATION, + 'session.state.timeout' => (60 * 60 * 10), // 10 hours /* * Option to override the default settings for the session cookie name @@ -896,8 +895,7 @@ * Note: The oldest data will always be deleted if the memcache server * runs out of storage space. */ - 'memcache_store.expires' => $SESSION_DURATION + 3600, // Session duration plus an hour for clock skew - + 'memcache_store.expires' => (60 * 60 * 10) + 3600, // Session duration (10 hours) plus an hour for clock skew /************************************* From cea197fb359f229ec9d74d01d57fbbe54536fc46 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:09:16 -0600 Subject: [PATCH 11/33] re-add the IDP_NAME variable for containers that still need it --- docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index becdb44..16108e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -278,6 +278,7 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp1" + IDP_NAME: "NA" SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJz1" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -300,6 +301,7 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp2" + IDP_NAME: "NA" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJz2" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -324,6 +326,7 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp3 + IDP_NAME: "NA" SECRET_SALT: h57fjemb&dn^nsJFGNjweJz3 SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -344,6 +347,7 @@ services: environment: ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp1 + IDP_NAME: THIS VARIABLE IS REQUIRED BUT PROBABLY NOT USED SECRET_SALT: NOT-a-secret-k49fjfkw73hjf9t87wjiw SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -360,6 +364,7 @@ services: env_file: - ./local.broker.env environment: + IDP_NAME: "idp" MYSQL_HOST: "brokerDb" MYSQL_DATABASE: "broker" MYSQL_USER: "user" From 0e35184652bf8811c2a19d7e0a5cf4b8a41f4914 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:52:07 -0600 Subject: [PATCH 12/33] add REMEMBER_ME_SECRET to local.env.dist [skip ci] --- local.env.dist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/local.env.dist b/local.env.dist index 47d955d..fec4ccf 100644 --- a/local.env.dist +++ b/local.env.dist @@ -73,6 +73,9 @@ MFA_LEARN_MORE_URL= # Example: https://pw.example.com/#/2sv/intro MFA_SETUP_URL= +# Secret key used in MFA remember me cookie generation +REMEMBER_ME_SECRET= + # silauth config # List any IP addresses and/or IP address ranges (CIDR) that should NOT be From 11f5138006ce4ea8c44364309c90624ba8cd7c74 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:55:32 -0600 Subject: [PATCH 13/33] throw exception if SP entityID can't be found in the state --- modules/sildisco/src/IdPDisco.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/modules/sildisco/src/IdPDisco.php b/modules/sildisco/src/IdPDisco.php index f32e606..c4e26e4 100644 --- a/modules/sildisco/src/IdPDisco.php +++ b/modules/sildisco/src/IdPDisco.php @@ -6,10 +6,12 @@ use Sil\SspUtils\DiscoUtils; use Sil\SspUtils\Metadata; use SimpleSAML\Auth; +use SimpleSAML\Error\NoState; use SimpleSAML\Logger; use SimpleSAML\Utils\HTTP; use SimpleSAML\XHTML\IdPDisco as SSPIdPDisco; use SimpleSAML\XHTML\Template; +use yii\db\Exception; /** * This class implements a custom IdP discovery service, for use with a ssp hub (proxy) @@ -39,6 +41,10 @@ private function getMetadataPath() return __DIR__ . '/../../../metadata/'; } + /** + * @throws NoState + * @throws Exception + */ private function getSPEntityIDAndReducedIdpList(): array { @@ -50,18 +56,23 @@ private function getSPEntityIDAndReducedIdpList(): array // Before the SimpleSAMLphp 2 upgrade, we added it to the state ourselves by overriding the SAML2.php file parse_str(parse_url($_GET['return'], PHP_URL_QUERY), $returnState); $state = Auth\State::loadState($returnState['AuthID'], 'saml:sp:sso'); - assert($state && array_key_exists('SPMetadata', $state)); + if (!array_key_exists('SPMetadata', $state)) { + throw new Exception('SPMetadata not found in state'); + } + $spmd = $state['SPMetadata']; $spEntityId = $spmd['entityid']; - - if (!empty($spEntityId)) { - $idpList = DiscoUtils::getReducedIdpList( - $idpList, - $this->getMetadataPath(), - $spEntityId - ); + if (empty($spEntityId)) { + throw new Exception('empty SP entityID'); } + $idpList = DiscoUtils::getReducedIdpList( + $idpList, + $this->getMetadataPath(), + $spEntityId + ); + + return array($spEntityId, $idpList); } From e995c8976fb262091eb0ada501a4cadccf40ca41 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 22 Jul 2024 12:33:07 -0600 Subject: [PATCH 14/33] simplify sildisco integration tests, removing equivalent scenarios --- behat.yml | 10 ++---- features/Sp1Idp2Sp2Sp3Idp1.feature | 22 ------------- features/Sp2Idp2Sp1Idp1Sp3.feature | 24 -------------- features/Sp2Idp2Sp1Idp2Sp3.feature | 22 ------------- features/Sp3Idp1Sp1Idp1Sp2Idp2.feature | 22 ------------- ...dp1Sp2Idp2Sp3.feature => sildisco.feature} | 31 ++++++++++++------- 6 files changed, 22 insertions(+), 109 deletions(-) delete mode 100644 features/Sp1Idp2Sp2Sp3Idp1.feature delete mode 100644 features/Sp2Idp2Sp1Idp1Sp3.feature delete mode 100644 features/Sp2Idp2Sp1Idp2Sp3.feature delete mode 100644 features/Sp3Idp1Sp1Idp1Sp2Idp2.feature rename features/{Sp1Idp1Sp2Idp2Sp3.feature => sildisco.feature} (50%) diff --git a/behat.yml b/behat.yml index 0e4f8ff..9ca6977 100644 --- a/behat.yml +++ b/behat.yml @@ -19,14 +19,10 @@ default: paths: [ '%paths.base%//features//profilereview.feature' ] contexts: [ 'ProfileReviewContext' ] sildisco_features: - contexts: ['SilDiscoContext'] + contexts: [ 'SilDiscoContext' ] paths: - - '%paths.base%//features//Sp1Idp1Sp2Idp2Sp3.feature' - - '%paths.base%//features//Sp1Idp2Sp2Sp3Idp1.feature' - - '%paths.base%//features//Sp2Idp2Sp1Idp1Sp3.feature' - - '%paths.base%//features//Sp2Idp2Sp1Idp2Sp3.feature' - - '%paths.base%//features//Sp3Idp1Sp1Idp1Sp2Idp2.feature' -# - '%paths.base%//features//WwwMetadataCept.feature' + - '%paths.base%//features//sildisco.feature' + # - '%paths.base%//features//WwwMetadataCept.feature' status_features: paths: [ '%paths.base%//features//status.feature' ] contexts: [ 'StatusContext' ] diff --git a/features/Sp1Idp2Sp2Sp3Idp1.feature b/features/Sp1Idp2Sp2Sp3Idp1.feature deleted file mode 100644 index fa32dcc..0000000 --- a/features/Sp1Idp2Sp2Sp3Idp1.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Ensure I can login to Sp1 through Idp2, am already logged in for Sp2, and must login to Sp3 through Idp1. - - Scenario: Login to SP1 through IDP2 - When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP1" - And I click on the "IDP 2" tile - And I log in using my "IDP 2" credentials - Then I should see my attributes on SP1 - - Scenario: After IDP2 login, go directly to SP2 without credentials - Given I have authenticated with IDP2 for SP1 - When I go to the SP2 login page - Then I should see my attributes on SP2 - - Scenario: After IDP2 login, go to SP3 through IDP1 - Given I have authenticated with IDP2 for SP1 - When I go to the SP3 login page - And I should see "to continue to SP3" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials - Then I should see my attributes on SP3 diff --git a/features/Sp2Idp2Sp1Idp1Sp3.feature b/features/Sp2Idp2Sp1Idp1Sp3.feature deleted file mode 100644 index 26d54bc..0000000 --- a/features/Sp2Idp2Sp1Idp1Sp3.feature +++ /dev/null @@ -1,24 +0,0 @@ -Feature: Ensure I can login to Sp2 through Idp2, must login to Sp1 if I choose Idp1, and don't need to login for Sp3. - - Scenario: Login to SP2 through IDP2 - When I go to the SP2 login page - And I log in using my "IDP 2" credentials - Then I should see my attributes on SP2 - - Scenario: Login to SP1 through IDP1 - Given I have authenticated with IDP2 for SP2 - When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials - Then I should see my attributes on SP1 - - Scenario: After IDP2 login, go directly to SP3 without credentials - Given I have authenticated with IDP2 for SP2 - And I have authenticated with IDP1 for SP1 - And I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP3" - And I click on the "IDP 1" tile - Then I should see my attributes on SP3 - diff --git a/features/Sp2Idp2Sp1Idp2Sp3.feature b/features/Sp2Idp2Sp1Idp2Sp3.feature deleted file mode 100644 index 7c73a54..0000000 --- a/features/Sp2Idp2Sp1Idp2Sp3.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Ensure I can login to Sp2 through Idp2, get discovery page for Sp1, and must login to Sp3 through Idp1. - - Scenario: Login to SP2 through IDP2 - When I go to the SP2 login page - And I log in using my "IDP 2" credentials - Then I should see my attributes on SP2 - - Scenario: Get discovery page for SP1 - Given I have authenticated with IDP2 for SP2 - When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 2" tile - Then I should see my attributes on SP1 - - Scenario: Must login to SP3 through IDP1 - Given I have authenticated with IDP2 for SP2 - When I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials - Then I should see my attributes on SP3 - diff --git a/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature b/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature deleted file mode 100644 index 2db76fa..0000000 --- a/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Ensure I can login to Sp3 through Idp1, get the discovery page for Sp1 and must login to Sp2 through Idp2. - - Scenario: login to SP3 using IDP1 - When I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP3" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials - Then I should see my attributes on SP3 - - Scenario: having authenticated with IDP1 for SP3, go to SP1 via the discovery page - Given I have authenticated with IDP1 for SP3 - When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile - Then I should see my attributes on SP1 - - Scenario: having authenticated with IDP1 for SP3, login to SP2 using IDP2 - Given I have authenticated with IDP1 for SP3 - When I go to the SP2 login page - And I log in using my "IDP 2" credentials - Then I should see my attributes on SP2 diff --git a/features/Sp1Idp1Sp2Idp2Sp3.feature b/features/sildisco.feature similarity index 50% rename from features/Sp1Idp1Sp2Idp2Sp3.feature rename to features/sildisco.feature index aaf4ee9..b0705fa 100644 --- a/features/Sp1Idp1Sp2Idp2Sp3.feature +++ b/features/sildisco.feature @@ -1,6 +1,6 @@ -Feature: Ensure I can login to Sp1 through Idp1, must login to Sp2 through Idp2 and am already logged in for Sp3. +Feature: SIL IdP discovery (sildisco) module - Scenario: Login to SP1 through IDP1 + Scenario: Expect discovery page and login prompt When I go to the SP1 login page And the url should match "sildisco/disco.php" And I should see "to continue to SP1" @@ -8,13 +8,12 @@ Feature: Ensure I can login to Sp1 through Idp1, must login to Sp2 through Idp2 And I log in using my "IDP 1" credentials Then I should see my attributes on SP1 - Scenario: After IDP1 login, go to SP2 through IDP2 - Given I have authenticated with IDP1 for SP1 - When I go to the SP2 login page + Scenario: Skip discovery page with only one approved IdP + Given I go to the SP2 login page And I log in using my "IDP 2" credentials Then I should see my attributes on SP2 - Scenario: After IDP1 login, go directly to SP3 without credentials + Scenario: Skip login prompt with existing authentication session Given I have authenticated with IDP1 for SP1 When I go to the SP3 login page And the url should match "sildisco/disco.php" @@ -22,12 +21,20 @@ Feature: Ensure I can login to Sp1 through Idp1, must login to Sp2 through Idp2 And I click on the "IDP 1" tile Then I should see my attributes on SP3 - Scenario: Logout of IDP1 + Scenario: Skip discovery and login prompt + Given I have authenticated with IDP2 for SP1 + When I go to the SP2 login page + Then I should see my attributes on SP2 + + Scenario: Show discovery AND login prompt with existing session on different IdP + Given I have authenticated with IDP2 for SP1 + When I go to the SP3 login page + And I should see "to continue to SP3" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials + Then I should see my attributes on SP3 + + Scenario: IdP Logout Given I have authenticated with IDP1 for SP1 When I log out of IDP1 Then I should see "You have now been logged out." - - Scenario: Logout of IDP2 - Given I have authenticated with IDP2 for SP2 - When I log out of IDP2 - Then I should see "You have now been logged out." From b3803f2f80c276621dee84c17b7406b3ea0c2cc9 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 22 Jul 2024 12:35:21 -0600 Subject: [PATCH 15/33] enable metadata test scenarios --- behat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat.yml b/behat.yml index 9ca6977..3f72620 100644 --- a/behat.yml +++ b/behat.yml @@ -22,7 +22,7 @@ default: contexts: [ 'SilDiscoContext' ] paths: - '%paths.base%//features//sildisco.feature' - # - '%paths.base%//features//WwwMetadataCept.feature' + - '%paths.base%//features//WwwMetadataCept.feature' status_features: paths: [ '%paths.base%//features//status.feature' ] contexts: [ 'StatusContext' ] From 60c742dfa836eecd331db0e5ea4642327b04719c Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:11:48 -0600 Subject: [PATCH 16/33] remove SPList from IDP1 test container Since all three SPs are listed, this is not needed. Also, by removing it, we can remove IDP3 since the absence of an SPList is the only unique aspect of IDP3 with respect to the sildisco tests. --- development/hub/metadata/idp-remote.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/development/hub/metadata/idp-remote.php b/development/hub/metadata/idp-remote.php index af01b35..a108fdb 100644 --- a/development/hub/metadata/idp-remote.php +++ b/development/hub/metadata/idp-remote.php @@ -25,10 +25,6 @@ 'SingleSignOnService' => 'http://ssp-idp1.local:8085/saml2/idp/SSOService.php', 'SingleLogoutService' => 'http://ssp-idp1.local:8085/saml2/idp/SingleLogoutService.php', 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', - - // NOTE: This breaks being able to test the hub's authentication sources - // since the hub doesn't create an SP entry in the session - 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082', 'http://ssp-sp3.local:8083'], ], 'http://ssp-idp1.local' => [ 'metadata-set' => 'saml20-idp-remote', @@ -44,12 +40,7 @@ 'SingleSignOnService' => 'http://ssp-idp1.local/saml2/idp/SSOService.php', 'SingleLogoutService' => 'http://ssp-idp1.local/saml2/idp/SingleLogoutService.php', - // 'certFingerprint' => 'c9ed4dfb07caf13fc21e0fec1572047eb8a7a4cb' 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', - - // NOTE: This breaks being able to test the hub's authentication sources - // since the hub doesn't create an SP entry in the session - 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local', 'http://ssp-sp3.local'], ], /* From c27c8ba6288b639a79ea9eb24009cc2b17dd2335 Mon Sep 17 00:00:00 2001 From: Jason Jackson Date: Tue, 23 Jul 2024 10:49:54 -0400 Subject: [PATCH 17/33] Fix announcement test --- tests/AnnouncementTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/AnnouncementTest.php b/tests/AnnouncementTest.php index f181cda..0cdb8a8 100644 --- a/tests/AnnouncementTest.php +++ b/tests/AnnouncementTest.php @@ -13,7 +13,11 @@ class AnnouncementTest extends TestCase */ public function testGetSimpleAnnouncement() { - $results = AnnouncementUtils::getSimpleAnnouncement(); + $announcementPathFile = '/data/ssp-announcement.php'; + if (file_exists($announcementPathFile)) { + $announcement = include $announcementPathFile; + $this->assertIsString($announcement); + } } } \ No newline at end of file From b742091a8b0ba20b15549d43f1f944a7769f29bb Mon Sep 17 00:00:00 2001 From: Jason Jackson Date: Tue, 23 Jul 2024 10:57:20 -0400 Subject: [PATCH 18/33] add description of metadata tests to README --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index eb46259..1faffa2 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,30 @@ docker composer up -d ssp-hub.local 13. Hit `Apply` and `OK` 14. Click on `Run` and then `Debug 'Debug on Docker'` +### Metadata Tests Check: +- Metadata files can be linted via php (`php -l file`) +- Metadata files return arrays +- IdP Metadata files have an IdP namespace that exists, is a string, and only contains letters, numbers, hyphens, and underscores +- IdP Metadata files don't have duplicate IdP codes +- SP Metadata files don't have duplicate entity ids +- IdP Metadatas contains `name` entry with an `en` entry +- IdP Metadatas contains `logoURL` entry +- if SP Metadata contains `IDPList`, check that it is allowed for that IdP as well + +#### Hub mode tests [SKIPPED if HUB_MODE = false] +- IdP Metadata files SP List is an array +- IdP Metadata files LogoCaption isset +- IdP Metadata files SP List has existing SPs +- All SPs have an IdP it can use +- All SPs have a non-empty IDPList entry +- All SPs have a non-empty name entry + +#### SP tests [SKIPPED if `'SkipTests' => true,`] +- Contains a `CertData` entry +- Contains a `saml20.sign.response` entry AND it is set to true +- Contains a `saml20.sign.assertion` entry AND it is set to true +- Contains a `assertion.encryption` entry AND it is set to true + ## Overriding translations / dictionaries If you use this Docker image but want to change some of the translations, you From 0987d5765beb6e870b905b30d1bb9de94c77766c Mon Sep 17 00:00:00 2001 From: Jason Jackson Date: Tue, 23 Jul 2024 10:59:36 -0400 Subject: [PATCH 19/33] Cleanup metadata tests --- tests/MetadataTest.php | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 4786677..39f7965 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -55,13 +55,13 @@ public function testMetadataFilesReturnArrays() $spFiles = $this->getSpMetadataFiles(); foreach ($spFiles as $file) { $returnVal = include $file; - $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); + $this->assertIsArray($returnVal, 'Metadata file does not return array as expected. File: ' . $file); } $idpFiles = $this->getIdPMetadataFiles(); foreach ($idpFiles as $file) { $returnVal = include $file; - $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); + $this->assertIsArray($returnVal, 'Metadata file does not return array as expected. File: ' . $file); } } @@ -74,7 +74,7 @@ public function testIDPRemoteMetadataIDPCode() 'include an ' . self::IdpCode . ' element as expected. IDP: ' . $entityId); $nextCode = $entry[self::IdpCode]; - $this->assertTrue(is_string($nextCode), 'Metadata entry has an ' . + $this->assertIsString($nextCode, 'Metadata entry has an ' . self::IdpCode . 'element that is not a string. IDP: ' . $entityId); $this->assertRegExp("/^[A-Za-z0-9_-]+$/", $nextCode, 'Metadata entry has an ' . self::IdpCode . ' element that has something other than letters, ' . @@ -101,7 +101,7 @@ public function testIDPRemoteMetadataBadSPList() } } - $this->assertTrue(empty($badIdps), + $this->assertEmpty($badIdps, "At least one IdP has an " . $spListKey . " entry that is not an array ... " . PHP_EOL . var_export($badIdps, True)); @@ -125,7 +125,7 @@ public function testIDPRemoteMetadataMissingLogoCaption() } } - $this->assertTrue(empty($badIdps), + $this->assertEmpty($badIdps, "At least one IdP is missing a " . self::LogoCaptionKey . " entry ... " . PHP_EOL . var_export($badIdps, True)); @@ -157,7 +157,7 @@ public function testIDPRemoteMetadataBadSPListEntry() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, "At least one non-existent SP is listed in an IdP's " . $spListKey . " entry ... " . PHP_EOL . var_export($badSps, True)); @@ -171,7 +171,7 @@ public function testIDPRemoteMetadataNoDuplicateIDPCode() foreach ($idpEntries as $entityId => $entry) { $nextCode = $entry[self::IdpCode]; - $this->assertFalse(in_array($nextCode, $codes), + $this->assertNotContains($nextCode, $codes, "Metadata has a duplicate " . self::IdpCode . " entry: " . $nextCode); $codes[] = $nextCode; } @@ -184,8 +184,7 @@ public function testMetadataNoDuplicateEntities() foreach ($spFiles as $file) { $returnVal = include $file; foreach ($returnVal as $entityId => $entity) { - $this->assertFalse( - in_array($entityId, $entities), + $this->assertNotContains($entityId, $entities, 'Duplicate entity id found in metadata file: ' . $file . '. Entity ID: ' . $entityId ); $entities[] = $entityId; @@ -196,8 +195,7 @@ public function testMetadataNoDuplicateEntities() foreach ($idpFiles as $file) { $returnVal = include $file; foreach ($returnVal as $entityId => $entity) { - $this->assertFalse( - in_array($entityId, $entities), + $this->assertNotContains($entityId, $entities, 'Duplicate entity id found in metadata file: ' . $file . '. Entity ID: ' . $entityId ); $entities[] = $entityId; @@ -227,7 +225,7 @@ public function testMetadataNoSpsWithoutAnIdp() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, "At least one SP does not have an IdP it is allowed to use ... " . var_export($badSps, True)); } @@ -244,7 +242,7 @@ public function testMetadataBadIdpName() } } - $this->assertTrue(empty($badNames), + $this->assertEmpty($badNames, "The following Idp's do not have a 'name' entry as an array with an 'en' entry ... " . var_export($badNames, True)); } @@ -261,7 +259,7 @@ public function testMetadataMissingLogoURL() } } - $this->assertTrue(empty($badLogos), + $this->assertEmpty($badLogos, "The following Idp's do not have a 'logoURL' entry ... " . var_export($badLogos, True)); } @@ -288,7 +286,7 @@ public function testMetadataSPWithBadIDPList() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has an IDPList with a bad IDP entity id ... ' . var_export($badSps, True)); } @@ -311,7 +309,7 @@ public function testMetadataSPWithNoIDPList() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has an empty IDPList entry (required) ... ' . var_export($badSps, True)); } @@ -334,7 +332,7 @@ public function testMetadataSPWithNoName() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has an empty "' . self::SPNameKey . '" entry (required) ... ' . var_export($badSps, True)); } @@ -356,7 +354,7 @@ public function testMetadataCerts() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has no certData entry ... ' . var_export($badSps, True)); @@ -382,7 +380,7 @@ public function testMetadataSignResponse() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has saml20.sign.response set to false ... ' . var_export($badSps, True)); @@ -412,7 +410,7 @@ public function testMetadataSignAssertion() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has saml20.sign.assertion set to false ... ' . var_export($badSps, True)); @@ -441,7 +439,7 @@ public function testMetadataEncryption() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP does not have assertion.encryption set to True ... ' . var_export($badSps, True)); From 7cf405e390b617fe76396c871da18ec73e054846 Mon Sep 17 00:00:00 2001 From: Jason Jackson Date: Fri, 26 Jul 2024 12:24:52 -0400 Subject: [PATCH 20/33] add getSimpleAnnouncement back to test --- tests/AnnouncementTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/AnnouncementTest.php b/tests/AnnouncementTest.php index 0cdb8a8..4334499 100644 --- a/tests/AnnouncementTest.php +++ b/tests/AnnouncementTest.php @@ -15,8 +15,8 @@ public function testGetSimpleAnnouncement() { $announcementPathFile = '/data/ssp-announcement.php'; if (file_exists($announcementPathFile)) { - $announcement = include $announcementPathFile; - $this->assertIsString($announcement); + $results = AnnouncementUtils::getSimpleAnnouncement(); + $this->assertNotNull($results); } } From 997f4f816aefa2781beabc670753e2f66da3005f Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Sun, 28 Jul 2024 21:10:41 +0800 Subject: [PATCH 21/33] use SSP MetaDataStorageHandler in sildisco auth procs --- .../src/Auth/Process/AddIdp2NameId.php | 14 +++---------- modules/sildisco/src/Auth/Process/LogUser.php | 16 ++++----------- .../sildisco/src/Auth/Process/TagGroup.php | 14 +++---------- modules/sildisco/tests/AddIdpTest.php | 8 +++++--- modules/sildisco/tests/TagGroupTest.php | 10 ++++++---- .../sildisco/tests/fixtures/config/config.php | 6 ++++++ .../tests/fixtures/metadata/idp-bad-code.php | 12 ----------- .../tests/fixtures/metadata/idp-bare.php | 7 ------- .../tests/fixtures/metadata/idp-good.php | 8 -------- .../fixtures/metadata/saml20-idp-remote.php | 20 +++++++++++++++++++ 10 files changed, 47 insertions(+), 68 deletions(-) create mode 100644 modules/sildisco/tests/fixtures/config/config.php delete mode 100644 modules/sildisco/tests/fixtures/metadata/idp-bad-code.php delete mode 100644 modules/sildisco/tests/fixtures/metadata/idp-bare.php delete mode 100644 modules/sildisco/tests/fixtures/metadata/idp-good.php create mode 100644 modules/sildisco/tests/fixtures/metadata/saml20-idp-remote.php diff --git a/modules/sildisco/src/Auth/Process/AddIdp2NameId.php b/modules/sildisco/src/Auth/Process/AddIdp2NameId.php index 1ec9232..b41f01c 100644 --- a/modules/sildisco/src/Auth/Process/AddIdp2NameId.php +++ b/modules/sildisco/src/Auth/Process/AddIdp2NameId.php @@ -3,10 +3,10 @@ namespace SimpleSAML\Module\sildisco\Auth\Process; use SAML2\XML\saml\NameID; -use Sil\SspUtils\Metadata; use SimpleSAML\Auth\ProcessingFilter; use SimpleSAML\Error; use SimpleSAML\Logger; +use SimpleSAML\Metadata\MetaDataStorageHandler; /** * Attribute filter for appending IDPNamespace to the NameID. @@ -134,16 +134,8 @@ public function process(array &$state): void return; } - // Get the potential IDPs from idp remote metadata - $metadataPath = __DIR__ . '/../../../../../metadata'; - - // If a unit test sends a different metadataPath, use it - if (isset($state['metadataPath'])) { - $metadataPath = $state['metadataPath']; - } - $idpEntries = Metadata::getIdpMetadataEntries($metadataPath); - - $idpEntry = $idpEntries[$samlIDP]; + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntry = $metadata->getMetaData($samlIDP, 'saml20-idp-remote'); // The IDP metadata must have an IDPNamespace entry if (!isset($idpEntry[self::IDP_CODE_KEY])) { diff --git a/modules/sildisco/src/Auth/Process/LogUser.php b/modules/sildisco/src/Auth/Process/LogUser.php index c13f1c1..6d59643 100644 --- a/modules/sildisco/src/Auth/Process/LogUser.php +++ b/modules/sildisco/src/Auth/Process/LogUser.php @@ -4,9 +4,9 @@ use Aws\DynamoDb\Marshaler; use Aws\Sdk; -use Sil\SspUtils\Metadata; use SimpleSAML\Auth\ProcessingFilter; use SimpleSAML\Logger; +use SimpleSAML\Metadata\MetaDataStorageHandler; /** * This Auth Proc logs information about each successful login to an AWS Dynamodb table. @@ -165,19 +165,11 @@ private function getIdp(array &$state) return 'No IDP available'; } - $samlIDP = $state[self::IDP_KEY]; - - // Get the potential IDPs from idp remote metadata - $metadataPath = __DIR__ . '/../../../../../metadata'; + $metadata = MetaDataStorageHandler::getMetadataHandler(); - // If a unit test sends a different metadataPath, use it - if (isset($state['metadataPath'])) { - $metadataPath = $state['metadataPath']; - } - $idpEntries = Metadata::getIdpMetadataEntries($metadataPath); + $samlIDP = $state[self::IDP_KEY]; - // Get the IDPNamespace or else just use the IDP's entity ID - $idpEntry = $idpEntries[$samlIDP]; + $idpEntry = $metadata->getMetaData($samlIDP, 'saml20-idp-remote'); // If the IDPNamespace entry is a string, use it if (isset($idpEntry[self::IDP_CODE_KEY]) && is_string($idpEntry[self::IDP_CODE_KEY])) { diff --git a/modules/sildisco/src/Auth/Process/TagGroup.php b/modules/sildisco/src/Auth/Process/TagGroup.php index 354244b..791d76a 100644 --- a/modules/sildisco/src/Auth/Process/TagGroup.php +++ b/modules/sildisco/src/Auth/Process/TagGroup.php @@ -2,8 +2,8 @@ namespace SimpleSAML\Module\sildisco\Auth\Process; -use Sil\SspUtils\Metadata; use SimpleSAML\Auth\ProcessingFilter; +use SimpleSAML\Metadata\MetaDataStorageHandler; /** * Attribute filter for prefixing group names @@ -50,19 +50,11 @@ public function process(array &$state): void return; } - // Get the potential IDPs from idp remote metadata - $metadataPath = __DIR__ . '/../../../../../metadata'; - - // If a unit test sends a different metadataPath, use it - if (isset($state['metadataPath'])) { - $metadataPath = $state['metadataPath']; - } - - $idpEntries = Metadata::getIdpMetadataEntries($metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); $samlIDP = $state["saml:sp:IdP"]; - $idpEntry = $idpEntries[$samlIDP]; + $idpEntry = $metadata->getMetaData($samlIDP, 'saml20-idp-remote'); /* * If the IDP metadata has an IDPNamespace entry, use that value. Otherwise, diff --git a/modules/sildisco/tests/AddIdpTest.php b/modules/sildisco/tests/AddIdpTest.php index 686eb07..5f99bfd 100644 --- a/modules/sildisco/tests/AddIdpTest.php +++ b/modules/sildisco/tests/AddIdpTest.php @@ -3,10 +3,15 @@ use PHPUnit\Framework\TestCase; use SAML2\XML\saml\NameID; +use SimpleSAML\Configuration; use SimpleSAML\Module\sildisco\Auth\Process\AddIdp2NameId; class AddIdpTest extends TestCase { + public static function setUpBeforeClass(): void + { + Configuration::setConfigDir(__DIR__ . '/fixtures/config/'); + } private static function getNameID($idp) { @@ -20,7 +25,6 @@ private static function getNameID($idp) ], ], 'Attributes' => [], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; } @@ -91,7 +95,6 @@ public function testAddIdp2NameId_GoodString() 'saml:sp:IdP' => 'idp-good', 'saml:sp:NameID' => $nameID, 'Attributes' => [], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $newNameID = new NameID(); @@ -119,7 +122,6 @@ public function testAddIdp2NameId_GoodArray() 'saml:sp:IdP' => 'idp-good', 'saml:sp:NameID' => $nameID, 'Attributes' => [], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $newNameID = $state['saml:sp:NameID']; diff --git a/modules/sildisco/tests/TagGroupTest.php b/modules/sildisco/tests/TagGroupTest.php index c54b8c0..c24f735 100644 --- a/modules/sildisco/tests/TagGroupTest.php +++ b/modules/sildisco/tests/TagGroupTest.php @@ -1,10 +1,16 @@ ['ADMINS'], 'member' => ['ADMINS'], ], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $expected = $request; @@ -55,7 +60,6 @@ public function testTagGroup_Member() "Attributes" => [ 'member' => ['ADMINS'], ], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $expected = $request; @@ -76,7 +80,6 @@ public function testTagGroup_Oid() "Attributes" => [ 'urn:oid:2.5.4.31' => ['ADMINS'], ], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $expected = $request; @@ -97,7 +100,6 @@ public function testTagGroup_IdpGood() "Attributes" => [ 'urn:oid:2.5.4.31' => ['ADMINS'], ], - 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; $expected = $request; diff --git a/modules/sildisco/tests/fixtures/config/config.php b/modules/sildisco/tests/fixtures/config/config.php new file mode 100644 index 0000000..950a88c --- /dev/null +++ b/modules/sildisco/tests/fixtures/config/config.php @@ -0,0 +1,6 @@ + ['sildisco' => true], + 'metadatadir' => __DIR__ . '/../metadata', +]; diff --git a/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php b/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php deleted file mode 100644 index 8df2684..0000000 --- a/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php +++ /dev/null @@ -1,12 +0,0 @@ - [ - 'SingleSignOnService' => 'http://idp-empty/saml2/idp/SSOService.php', - 'IDPNamespace' => '', - ], - 'idp-bad' => [ - 'SingleSignOnService' => 'http://idp-bad/saml2/idp/SSOService.php', - 'IDPNamespace' => 'ba!d!', - ], -]; diff --git a/modules/sildisco/tests/fixtures/metadata/idp-bare.php b/modules/sildisco/tests/fixtures/metadata/idp-bare.php deleted file mode 100644 index b5a4797..0000000 --- a/modules/sildisco/tests/fixtures/metadata/idp-bare.php +++ /dev/null @@ -1,7 +0,0 @@ - [ - 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', - ], -]; diff --git a/modules/sildisco/tests/fixtures/metadata/idp-good.php b/modules/sildisco/tests/fixtures/metadata/idp-good.php deleted file mode 100644 index 4cafa7c..0000000 --- a/modules/sildisco/tests/fixtures/metadata/idp-good.php +++ /dev/null @@ -1,8 +0,0 @@ - [ - 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', - 'IDPNamespace' => 'idpGood', - ], -]; diff --git a/modules/sildisco/tests/fixtures/metadata/saml20-idp-remote.php b/modules/sildisco/tests/fixtures/metadata/saml20-idp-remote.php new file mode 100644 index 0000000..5c76c18 --- /dev/null +++ b/modules/sildisco/tests/fixtures/metadata/saml20-idp-remote.php @@ -0,0 +1,20 @@ + 'http://idp-empty/saml2/idp/SSOService.php', + 'IDPNamespace' => '', +]; + +$metadata['idp-bad'] = [ + 'SingleSignOnService' => 'http://idp-bad/saml2/idp/SSOService.php', + 'IDPNamespace' => 'ba!d!', +]; + +$metadata['idp-bare'] = [ + 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', +]; + +$metadata['idp-good'] = [ + 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', + 'IDPNamespace' => 'idpGood', +]; From a03602a24de83493083a3e3152b8474473889813 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Sun, 28 Jul 2024 21:27:54 +0800 Subject: [PATCH 22/33] don't use SspUtils\Metadata in MetadataTest.php --- tests/MetadataTest.php | 141 ++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 93 deletions(-) diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 4786677..5712826 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -7,8 +7,8 @@ use PHPUnit\Framework\TestCase; use Sil\PhpEnv\Env; use Sil\SspUtils\DiscoUtils; -use Sil\SspUtils\Metadata; use Sil\SspUtils\Utils; +use SimpleSAML\Metadata\MetaDataStorageHandler; class MetadataTest extends TestCase { @@ -25,49 +25,10 @@ class MetadataTest extends TestCase public $metadataPath = __DIR__ . '/../vendor/simplesamlphp/simplesamlphp/metadata'; - public function testLintTestMetadataFiles() - { - $spFiles = $this->getSpMetadataFiles(); - foreach ($spFiles as $file) { - $output = $returnVal = null; - exec('php -l ' . $file, $output, $returnVal); - $this->assertEquals( - 0, - $returnVal, - 'Lint test failed for file: ' . $file . '. Error: ' . print_r($output, true) - ); - } - - $idpFiles = $this->getIdPMetadataFiles(); - foreach ($idpFiles as $file) { - $output = $returnVal = null; - exec('php -l ' . $file, $output, $returnVal); - $this->assertEquals( - 0, - $returnVal, - 'Lint test failed for file: ' . $file . '. Error: ' . print_r($output, true) - ); - } - } - - public function testMetadataFilesReturnArrays() - { - $spFiles = $this->getSpMetadataFiles(); - foreach ($spFiles as $file) { - $returnVal = include $file; - $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); - } - - $idpFiles = $this->getIdPMetadataFiles(); - foreach ($idpFiles as $file) { - $returnVal = include $file; - $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); - } - } - public function testIDPRemoteMetadataIDPCode() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); foreach ($idpEntries as $entityId => $entry) { $this->assertTrue(isset($entry[self::IdpCode]), 'Metadata entry does not ' . @@ -92,7 +53,8 @@ public function testIDPRemoteMetadataBadSPList() $badIdps = []; - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $spListKey = Utils::SP_LIST_KEY; foreach ($idpEntries as $entityId => $entry) { @@ -117,7 +79,8 @@ public function testIDPRemoteMetadataMissingLogoCaption() $badIdps = []; - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); foreach ($idpEntries as $entityId => $entry) { if (!isset($entry[self::LogoCaptionKey])) { @@ -140,11 +103,12 @@ public function testIDPRemoteMetadataBadSPListEntry() return; } - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $idpEntries = $metadata->getList(); $spListKey = Utils::SP_LIST_KEY; foreach ($idpEntries as $entityId => $entry) { @@ -166,7 +130,8 @@ public function testIDPRemoteMetadataBadSPListEntry() public function testIDPRemoteMetadataNoDuplicateIDPCode() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $codes = []; foreach ($idpEntries as $entityId => $entry) { @@ -179,29 +144,24 @@ public function testIDPRemoteMetadataNoDuplicateIDPCode() public function testMetadataNoDuplicateEntities() { + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $entities = []; - $spFiles = $this->getSpMetadataFiles(); - foreach ($spFiles as $file) { - $returnVal = include $file; - foreach ($returnVal as $entityId => $entity) { - $this->assertFalse( - in_array($entityId, $entities), - 'Duplicate entity id found in metadata file: ' . $file . '. Entity ID: ' . $entityId - ); - $entities[] = $entityId; - } + foreach ($spEntries as $entityId => $entity) { + $this->assertFalse( + in_array($entityId, $entities), + 'Duplicate SP entityId found: ' . $entityId + ); + $entities[] = $entityId; } - $idpFiles = $this->getIdPMetadataFiles(); - foreach ($idpFiles as $file) { - $returnVal = include $file; - foreach ($returnVal as $entityId => $entity) { - $this->assertFalse( - in_array($entityId, $entities), - 'Duplicate entity id found in metadata file: ' . $file . '. Entity ID: ' . $entityId - ); - $entities[] = $entityId; - } + $idpEntries = $metadata->getList(); + foreach ($idpEntries as $entityId => $entity) { + $this->assertFalse( + in_array($entityId, $entities), + 'Duplicate IdP entityId found: ' . $entityId + ); + $entities[] = $entityId; } } @@ -213,7 +173,8 @@ public function testMetadataNoSpsWithoutAnIdp() return; } - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; foreach ($spEntries as $spEntityId => $spEntry) { @@ -234,7 +195,8 @@ public function testMetadataNoSpsWithoutAnIdp() public function testMetadataBadIdpName() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $badNames = []; @@ -251,7 +213,8 @@ public function testMetadataBadIdpName() public function testMetadataMissingLogoURL() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $badLogos = []; @@ -269,8 +232,9 @@ public function testMetadataMissingLogoURL() public function testMetadataSPWithBadIDPList() { $idpListKey = Utils::IDP_LIST_KEY; - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -301,7 +265,8 @@ public function testMetadataSPWithNoIDPList() return; } $idpListKey = Utils::IDP_LIST_KEY; - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -324,7 +289,8 @@ public function testMetadataSPWithNoName() return; } - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -341,7 +307,8 @@ public function testMetadataSPWithNoName() public function testMetadataCerts() { - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -365,7 +332,8 @@ public function testMetadataCerts() public function testMetadataSignResponse() { // $this->markTestSkipped('Disabled for testing/verification'); - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; $skippedSps = []; @@ -395,7 +363,8 @@ public function testMetadataSignResponse() public function testMetadataSignAssertion() { // $this->markTestSkipped('Disabled for testing/verification'); - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; $skippedSps = []; @@ -425,7 +394,8 @@ public function testMetadataSignAssertion() public function testMetadataEncryption() { // $this->markTestSkipped('Wait until we require encryption.'); - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; $skippedSps = []; @@ -450,19 +420,4 @@ public function testMetadataEncryption() ' metadata entry set ... ' . var_export($skippedSps, True)); } } - - public function getSpMetadataFiles() - { - return $this->getFileList('sp'); - } - - public function getIdPMetadataFiles() - { - return $this->getFileList('idp'); - } - - public function getFileList($prefix) - { - return Metadata::getMetadataFiles($this->metadataPath, $prefix); - } } From 4a3073e5883d1a47b65fe7e0dd6e8e235b51ebcb Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 29 Jul 2024 07:22:17 +0800 Subject: [PATCH 23/33] fix metadata tests --- development/hub/config/authsources.php | 2 +- development/idp-local/metadata/saml20-sp-remote.php | 1 + docker-compose.yml | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/development/hub/config/authsources.php b/development/hub/config/authsources.php index c3a20cb..fe1b513 100644 --- a/development/hub/config/authsources.php +++ b/development/hub/config/authsources.php @@ -13,7 +13,7 @@ // The URL to the discovery service. // Can be NULL/unset, in which case a builtin discovery service will be used. 'discoURL' => 'http://ssp-hub.local/module.php/sildisco/disco.php', - + 'privatekey' => 'saml.pem', ], // This is a authentication source which handles admin authentication. diff --git a/development/idp-local/metadata/saml20-sp-remote.php b/development/idp-local/metadata/saml20-sp-remote.php index 4720d9a..7e46ff4 100644 --- a/development/idp-local/metadata/saml20-sp-remote.php +++ b/development/idp-local/metadata/saml20-sp-remote.php @@ -14,4 +14,5 @@ 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-acs.php/hub-discovery', 'SingleLogoutService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-logout.php/hub-discovery', 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', + 'assertion.encryption' => true, ]; diff --git a/docker-compose.yml b/docker-compose.yml index 16108e9..752cf38 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -179,6 +179,7 @@ services: BASE_URL_PATH: "http://ssp-idp1.local/" # change this to "http://ssp-idp1.local:8085" for manual browser testing HELP_CENTER_URL: "https://example.org/help" THEME_COLOR_SCHEME: "blue_grey-teal" + HUB_MODE: "false" ssp-idp2.local: build: . @@ -226,6 +227,7 @@ services: SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "red-teal" + HUB_MODE: "false" ssp-idp3.local: build: . @@ -258,6 +260,7 @@ services: SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "orange-light_blue" + HUB_MODE: "false" ssp-sp1.local: image: silintl/ssp-base:9.3.0 From 9c4a5abe61d1cc17560380e81b5c11f0ab4690ca Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 29 Jul 2024 08:09:58 +0800 Subject: [PATCH 24/33] use MetaDataStorageHandler in IdPDisco.php --- modules/sildisco/src/IdPDisco.php | 60 ++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/modules/sildisco/src/IdPDisco.php b/modules/sildisco/src/IdPDisco.php index c4e26e4..2bc190a 100644 --- a/modules/sildisco/src/IdPDisco.php +++ b/modules/sildisco/src/IdPDisco.php @@ -3,11 +3,12 @@ namespace SimpleSAML\Module\sildisco; use Sil\SspUtils\AnnouncementUtils; -use Sil\SspUtils\DiscoUtils; -use Sil\SspUtils\Metadata; +use Sil\SspUtils\Utils; use SimpleSAML\Auth; +use SimpleSAML\Error\MetadataNotFound; use SimpleSAML\Error\NoState; use SimpleSAML\Logger; +use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Utils\HTTP; use SimpleSAML\XHTML\IdPDisco as SSPIdPDisco; use SimpleSAML\XHTML\Template; @@ -35,12 +36,6 @@ protected function log(string $message): void Logger::info('SildiscoIdPDisco.' . $this->instance . ': ' . $message); } - /* Path to the folder with the SP and IdP metadata */ - private function getMetadataPath() - { - return __DIR__ . '/../../../metadata/'; - } - /** * @throws NoState * @throws Exception @@ -66,12 +61,7 @@ private function getSPEntityIDAndReducedIdpList(): array throw new Exception('empty SP entityID'); } - $idpList = DiscoUtils::getReducedIdpList( - $idpList, - $this->getMetadataPath(), - $spEntityId - ); - + $idpList = self::getReducedIdpList($idpList, $spEntityId); return array($spEntityId, $idpList); } @@ -103,9 +93,8 @@ public function handleRequest(): void } } - // Get the SP metadata entry - $spEntries = Metadata::getSpMetadataEntries($this->getMetadataPath()); - $sp = $spEntries[$spEntityId]; + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $sp = $metadata->getMetaData($spEntityId, 'saml20-sp-remote'); $t = new Template($this->config, 'selectidp-links', 'disco'); @@ -165,4 +154,41 @@ protected function validateIdP(?string $idp): ?string // the entity id wasn't valid return null; } + + /** + * Takes the original IDP List and reduces it down to the ones the current SP is meant to see. + * The relevant entries in saml20-idp-remote.php would be ... + * - 'excludeByDefault' (boolean), which when set to True would keep this idp from being + * shown to SP's that don't explicitly include it in the 'IDPList' entry of their metadata. + * - 'SPList' (array), which when set would only allow this idp to be shown + * to SPs whose entity_id is included in this array. + * + * @param array $idpList + * @param string $spEntityId - the current SP's entity id + * @return array of a subset of the original $startSources. + * @throws MetadataNotFound + */ + public static function getReducedIdpList(array $idpList, string $spEntityId): array + { + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spMetadata = $metadata->getMetaData($spEntityId, 'saml20-sp-remote'); + + $reducedIdpList = []; + + $idpListForSp = []; // The list of IDP's this SP wants to know about + if (array_key_exists(Utils::IDP_LIST_KEY, $spMetadata)) { + $idpListForSp = $spMetadata[Utils::IDP_LIST_KEY]; + } + + foreach ($idpList as $idpEntityId => $idpMdEntry) { + if (Utils::isIdpValidForSp($idpEntityId, + $idpMdEntry, + $spEntityId, + $idpListForSp) + ) { + $reducedIdpList[$idpEntityId] = $idpMdEntry; + } + } + return $reducedIdpList; + } } From 19e100dece16f57ce2dc1f3f9e5e87f7bfe8990a Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 29 Jul 2024 08:49:08 +0800 Subject: [PATCH 25/33] use MetaDataStorageHandler in run-spidplinks.php --- dockerbuild/run-spidplinks.php | 67 +++++++++++++++++++++++++++++-- modules/sildisco/src/IdPDisco.php | 15 +++++++ tests/MetadataTest.php | 7 +--- 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/dockerbuild/run-spidplinks.php b/dockerbuild/run-spidplinks.php index 82e3f72..2a6e083 100644 --- a/dockerbuild/run-spidplinks.php +++ b/dockerbuild/run-spidplinks.php @@ -2,10 +2,69 @@ include "/data/vendor/autoload.php"; -use Sil\SspUtils\DiscoUtils; +use SimpleSAML\Metadata\MetaDataStorageHandler; +use SimpleSAML\Module\sildisco\IdPDisco; -$mdPath = "/data/vendor/simplesamlphp/simplesamlphp/metadata"; +echo listAllSpIdpLinks(); -$results = DiscoUtils::listAllSpIdpLinks($mdPath, "nothtml"); +/** + * Returns a nested array of all the IdP's that are available to each SP + * + * @return array ["sp1" => ["idp1", ...], ...]] + */ +function getSpIdpLinks(): array +{ + $links = []; + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); -echo $results["text"]; + foreach ($spEntries as $spEntityId => $spEntry) { + $idpList = IdPDisco::getIdpsForSp($spEntityId); + $links[$spEntityId] = array_keys($idpList); + } + return $links; +} + +/** + * Returns a nested array of all the SPs that are allowed to use each IdP + * and all the IdPs that are available to each SP + */ +function listAllSpIdpLinks(): string +{ + $spLinks = getSpIdpLinks(); + $idpLinks = []; + + // transpose the SP-based array for the IdP-based array + foreach ($spLinks as $nextSp => $idps) { + foreach ($idps as $nextIdp) { + if (!isset($idpLinks[$nextIdp])) { + $idpLinks[$nextIdp] = []; + } + $idpLinks[$nextIdp][] = $nextSp; + } + } + + $output = PHP_EOL . "These IdPs are available to the corresponding SPs" . PHP_EOL; + + foreach ($idpLinks as $idpEntityId => $spList) { + $output .= ' ' . $idpEntityId . ' is available to ...' . PHP_EOL; + foreach ($spList as $nextSp) { + $output .= ' ' . $nextSp . PHP_EOL; + } + $output .= '-----------' . PHP_EOL; + $output .= PHP_EOL; + } + + $output .= PHP_EOL . "These SPs may use the corresponding IdPs" . PHP_EOL; + + foreach ($spLinks as $spEntityId => $idpList) { + $output .= ' ' . $spEntityId . ' may use ... ' . PHP_EOL; + foreach ($idpList as $nextIdp) { + $output .= ' ' . $nextIdp . PHP_EOL; + } + $output .= '-----------' . PHP_EOL; + $output .= PHP_EOL; + } + + return $output; +} diff --git a/modules/sildisco/src/IdPDisco.php b/modules/sildisco/src/IdPDisco.php index 2bc190a..97eccd8 100644 --- a/modules/sildisco/src/IdPDisco.php +++ b/modules/sildisco/src/IdPDisco.php @@ -191,4 +191,19 @@ public static function getReducedIdpList(array $idpList, string $spEntityId): ar } return $reducedIdpList; } + + /** + * Takes the original idp entries and reduces them down to the ones the current SP is meant to see. + * + * @param string $spEntityId + * @return array + * @throws MetadataNotFound + */ + public static function getIdpsForSp(string $spEntityId): array + { + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); + + return self::getReducedIdpList($idpEntries, $spEntityId); + } } diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 5712826..15d0571 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -6,9 +6,9 @@ use PHPUnit\Framework\TestCase; use Sil\PhpEnv\Env; -use Sil\SspUtils\DiscoUtils; use Sil\SspUtils\Utils; use SimpleSAML\Metadata\MetaDataStorageHandler; +use SimpleSAML\Module\sildisco\IdPDisco; class MetadataTest extends TestCase { @@ -178,10 +178,7 @@ public function testMetadataNoSpsWithoutAnIdp() $badSps = []; foreach ($spEntries as $spEntityId => $spEntry) { - $results = DiscoUtils::getIdpsForSp( - $spEntityId, - $this->metadataPath - ); + $results = IdPDisco::getIdpsForSp($spEntityId); if (empty($results)) { $badSps[] = $spEntityId; From fbc7da59b6f825f197c4fef917c86eee26fc6aef Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:38:44 +0800 Subject: [PATCH 26/33] use the normal SimpleSAMLphp metadata file format --- development/hub/metadata/idp-remote.php | 210 +++++++++--------- development/hub/metadata/sp-remote.php | 144 ++++++------ .../ssp-overrides/saml20-idp-remote.php | 8 +- .../ssp-overrides/saml20-sp-remote.php | 8 +- 4 files changed, 181 insertions(+), 189 deletions(-) diff --git a/development/hub/metadata/idp-remote.php b/development/hub/metadata/idp-remote.php index a108fdb..b9a56f9 100644 --- a/development/hub/metadata/idp-remote.php +++ b/development/hub/metadata/idp-remote.php @@ -6,119 +6,117 @@ * * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote */ -return [ - /* - * IdP 1 - */ - 'http://ssp-idp1.local:8085' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp1.local:8085', - 'name' => [ - 'en' => 'IDP 1:8085', - ], - 'IDPNamespace' => 'IDP-1-custom-port', - 'logoCaption' => 'IDP-1:8085 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1+8085', - - 'description' => 'Local IDP for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp1.local:8085/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp1.local:8085/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', + +/* + * IdP 1 + */ +$metadata['http://ssp-idp1.local:8085'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp1.local:8085', + 'name' => [ + 'en' => 'IDP 1:8085', ], - 'http://ssp-idp1.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp1.local', - 'name' => [ - 'en' => 'IDP 1', - ], - 'IDPNamespace' => 'IDP-1', - 'logoCaption' => 'IDP-1 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1', - - 'description' => 'Local IDP for testing SSP Hub (default port)', - - 'SingleSignOnService' => 'http://ssp-idp1.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp1.local/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', + 'IDPNamespace' => 'IDP-1-custom-port', + 'logoCaption' => 'IDP-1:8085 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1+8085', + + 'description' => 'Local IDP for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp1.local:8085/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp1.local:8085/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', +]; +$metadata['http://ssp-idp1.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp1.local', + 'name' => [ + 'en' => 'IDP 1', ], + 'IDPNamespace' => 'IDP-1', + 'logoCaption' => 'IDP-1 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1', + + 'description' => 'Local IDP for testing SSP Hub (default port)', - /* - * IdP 2 - */ - 'http://ssp-idp2.local:8086' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp2.local:8086', - 'name' => [ - 'en' => 'IDP 2:8086', - ], - 'IDPNamespace' => 'IDP-2-custom-port', - 'logoCaption' => 'IDP-2:8086 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2+8086', - - 'description' => 'Local IDP2 for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp2.local:8086/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp2.local:8086/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - - // limit which Sps can use this IdP - 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082'], + 'SingleSignOnService' => 'http://ssp-idp1.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp1.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', +]; + +/* + * IdP 2 + */ +$metadata['http://ssp-idp2.local:8086'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp2.local:8086', + 'name' => [ + 'en' => 'IDP 2:8086', ], - 'http://ssp-idp2.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp2.local', - 'name' => [ - 'en' => 'IDP 2', - ], - 'IDPNamespace' => 'IDP-2', - 'logoCaption' => 'IDP-2 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2', - - 'description' => 'Local IDP2 for testing SSP Hub (normal port)', - - 'SingleSignOnService' => 'http://ssp-idp2.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp2.local/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - - // limit which Sps can use this IdP - 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local'], + 'IDPNamespace' => 'IDP-2-custom-port', + 'logoCaption' => 'IDP-2:8086 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2+8086', + + 'description' => 'Local IDP2 for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp2.local:8086/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp2.local:8086/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', + + // limit which Sps can use this IdP + 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082'], +]; +$metadata['http://ssp-idp2.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp2.local', + 'name' => [ + 'en' => 'IDP 2', ], + 'IDPNamespace' => 'IDP-2', + 'logoCaption' => 'IDP-2 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2', + + 'description' => 'Local IDP2 for testing SSP Hub (normal port)', + + 'SingleSignOnService' => 'http://ssp-idp2.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp2.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', + + // limit which Sps can use this IdP + 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local'], +]; - /* - * IdP 3 - */ - 'http://ssp-idp3.local:8087' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp3.local:8087', - 'name' => [ - 'en' => 'IDP 3:8087', - ], - 'IDPNamespace' => 'IDP-3-custom-port', - 'logoCaption' => 'IDP-3:8087 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3+8087', - - 'description' => 'Local IDP3 for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp3.local:8087/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp3.local:8087/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', +/* + * IdP 3 + */ +$metadata['http://ssp-idp3.local:8087'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp3.local:8087', + 'name' => [ + 'en' => 'IDP 3:8087', ], - 'http://ssp-idp3.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp3.local', - 'name' => [ - 'en' => 'IDP 3', - ], - 'IDPNamespace' => 'IDP-3', - 'logoCaption' => 'IDP-3 staff', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3', - - 'description' => 'Local IDP3 for testing SSP Hub', - - 'SingleSignOnService' => 'http://ssp-idp3.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp3.local/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', + 'IDPNamespace' => 'IDP-3-custom-port', + 'logoCaption' => 'IDP-3:8087 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3+8087', + + 'description' => 'Local IDP3 for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp3.local:8087/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp3.local:8087/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', +]; +$metadata['http://ssp-idp3.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp3.local', + 'name' => [ + 'en' => 'IDP 3', ], + 'IDPNamespace' => 'IDP-3', + 'logoCaption' => 'IDP-3 staff', + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3', + + 'description' => 'Local IDP3 for testing SSP Hub', + 'SingleSignOnService' => 'http://ssp-idp3.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp3.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', ]; diff --git a/development/hub/metadata/sp-remote.php b/development/hub/metadata/sp-remote.php index 0bc515c..c8853ab 100644 --- a/development/hub/metadata/sp-remote.php +++ b/development/hub/metadata/sp-remote.php @@ -5,89 +5,87 @@ * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-sp-remote */ -return [ - /* - * Example SimpleSAMLphp SAML 2.0 SP - */ - 'http://ssp-sp1.local:8081' => [ - 'entityid' => 'http://ssp-sp1.local:8081', - 'name' => ['en' => 'SP1 (custom port)'], - 'AssertionConsumerService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', - 'SingleLogoutService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'IDPList' => [ - 'http://ssp-idp1.local:8085', - 'http://ssp-idp2.local:8086', - 'http://ssp-idp3.local:8087', - ], - 'assertion.encryption' => true, +/* + * Example SimpleSAMLphp SAML 2.0 SP + */ +$metadata['http://ssp-sp1.local:8081'] = [ + 'entityid' => 'http://ssp-sp1.local:8081', + 'name' => ['en' => 'SP1 (custom port)'], + 'AssertionConsumerService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', + 'SingleLogoutService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'IDPList' => [ + 'http://ssp-idp1.local:8085', + 'http://ssp-idp2.local:8086', + 'http://ssp-idp3.local:8087', ], + 'assertion.encryption' => true, +]; - 'http://ssp-sp1.local' => [ - 'entityid' => 'http://ssp-sp1.local', - 'name' => ['en' => 'SP1'], - 'AssertionConsumerService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'IDPList' => [ - 'http://ssp-idp1.local', - 'http://ssp-idp2.local', - 'http://ssp-idp3.local', - ], - 'assertion.encryption' => true, +$metadata['http://ssp-sp1.local'] = [ + 'entityid' => 'http://ssp-sp1.local', + 'name' => ['en' => 'SP1'], + 'AssertionConsumerService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'IDPList' => [ + 'http://ssp-idp1.local', + 'http://ssp-idp2.local', + 'http://ssp-idp3.local', ], + 'assertion.encryption' => true, +]; - 'http://ssp-sp2.local:8082' => [ - 'entityid' => 'http://ssp-sp2.local:8082', - 'name' => ['en' => 'SP2 (custom port)'], - 'AssertionConsumerService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', - 'SingleLogoutService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', - 'IDPList' => [ - 'http://ssp-idp2.local:8086', - ], - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, +$metadata['http://ssp-sp2.local:8082'] = [ + 'entityid' => 'http://ssp-sp2.local:8082', + 'name' => ['en' => 'SP2 (custom port)'], + 'AssertionConsumerService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', + 'SingleLogoutService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', + 'IDPList' => [ + 'http://ssp-idp2.local:8086', ], + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; - 'http://ssp-sp2.local' => [ - 'entityid' => 'http://ssp-sp2.local', - 'name' => ['en' => 'SP2'], - 'AssertionConsumerService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp2.local', - ], - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, +$metadata['http://ssp-sp2.local'] = [ + 'entityid' => 'http://ssp-sp2.local', + 'name' => ['en' => 'SP2'], + 'AssertionConsumerService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp2.local', ], + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; - // for test purposes, SP3 should be on the SPList entry of idp2 +// for test purposes, SP3 should be on the SPList entry of idp2 - 'http://ssp-sp3.local:8083' => [ - 'entityid' => 'http://ssp-sp3.local:8083', - 'name' => ['en' => 'SP3 (custom port)'], - 'AssertionConsumerService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp1.local:8085', - 'http://ssp-idp2.local:8086', // overruled by Idp2 - 'http://ssp-idp3.local:8087' - ], - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, +$metadata['http://ssp-sp3.local:8083'] = [ + 'entityid' => 'http://ssp-sp3.local:8083', + 'name' => ['en' => 'SP3 (custom port)'], + 'AssertionConsumerService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp1.local:8085', + 'http://ssp-idp2.local:8086', // overruled by Idp2 + 'http://ssp-idp3.local:8087' ], + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; - 'http://ssp-sp3.local' => [ - 'entityid' => 'http://ssp-sp3.local', - 'name' => ['en' => 'SP3'], - 'AssertionConsumerService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp1.local', - 'http://ssp-idp2.local', // overruled by Idp2 - 'http://ssp-idp3.local' - ], - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, +$metadata['http://ssp-sp3.local'] = [ + 'entityid' => 'http://ssp-sp3.local', + 'name' => ['en' => 'SP3'], + 'AssertionConsumerService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp1.local', + 'http://ssp-idp2.local', // overruled by Idp2 + 'http://ssp-idp3.local' ], + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, ]; diff --git a/dockerbuild/ssp-overrides/saml20-idp-remote.php b/dockerbuild/ssp-overrides/saml20-idp-remote.php index a5d0b1b..786e2ae 100644 --- a/dockerbuild/ssp-overrides/saml20-idp-remote.php +++ b/dockerbuild/ssp-overrides/saml20-idp-remote.php @@ -2,10 +2,8 @@ use Sil\SspUtils\Metadata; -$mdPath = __DIR__; +$files = Metadata::getMetadataFiles(__DIR__, 'idp'); -$startMetadata = Metadata::getIdpMetadataEntries($mdPath); - -foreach ($startMetadata as $key => $value) { - $metadata[$key] = $value; +foreach ($files as $file) { + include $file; } diff --git a/dockerbuild/ssp-overrides/saml20-sp-remote.php b/dockerbuild/ssp-overrides/saml20-sp-remote.php index c9e9758..3651cde 100644 --- a/dockerbuild/ssp-overrides/saml20-sp-remote.php +++ b/dockerbuild/ssp-overrides/saml20-sp-remote.php @@ -2,10 +2,8 @@ use Sil\SspUtils\Metadata; -$mdPath = __DIR__; +$files = Metadata::getMetadataFiles(__DIR__, 'sp'); -$startMetadata = Metadata::getSpMetadataEntries($mdPath); - -foreach ($startMetadata as $key => $value) { - $metadata[$key] = $value; +foreach ($files as $file) { + include $file; } From de2beb7a6fa1b54d8dbcfecae1dae8309ce0f03c Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:00:41 +0800 Subject: [PATCH 27/33] don't provide any metadata; add instructions to README --- Dockerfile | 2 - README.md | 84 +++++++++++++++++++ .../ssp-overrides/saml20-idp-remote.php | 9 -- .../ssp-overrides/saml20-sp-remote.php | 9 -- 4 files changed, 84 insertions(+), 20 deletions(-) delete mode 100644 dockerbuild/ssp-overrides/saml20-idp-remote.php delete mode 100644 dockerbuild/ssp-overrides/saml20-sp-remote.php diff --git a/Dockerfile b/Dockerfile index 35a56ac..521727e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,8 +43,6 @@ COPY modules/material/themes/material/profilereview/* $SSP_PATH/modules/profiler COPY modules/material/themes/material/silauth/* $SSP_PATH/modules/silauth/templates/ # Copy in SSP override files -COPY dockerbuild/ssp-overrides/saml20-idp-remote.php $SSP_PATH/metadata/saml20-idp-remote.php -COPY dockerbuild/ssp-overrides/saml20-sp-remote.php $SSP_PATH/metadata/saml20-sp-remote.php COPY dockerbuild/config/* $SSP_PATH/config/ COPY dockerbuild/ssp-overrides/sp-php.patch sp-php.patch RUN patch /data/vendor/simplesamlphp/simplesamlphp/modules/saml/src/Auth/Source/SP.php sp-php.patch diff --git a/README.md b/README.md index eb46259..2641187 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,90 @@ The content of the configuration profile takes the form of a typical .env file, `#` for comments and `=` for variable assignment. Any variables read from AppConfig will overwrite variables set in the execution environment. +### SimpleSAMLphp Metadata + +No metadata files are included by default. All metadata configuration must be provided +by using ssp-base as a base image and adding files to the +`/data/vendor/simplesamlphp/simplesamlphp/metadata` directory. `SSP_BASE` is defined by +ssp-base as shorthand for `/data/vendor/simplesamlphp/simplesamlphp`. + +```Dockerfile +COPY metadata/* $SSP_PATH/metadata/ +``` + +#### Legacy Metadata Format + +Prior to version 10 of ssp-base, the saml20-idp-remote and saml20-sp-remote files contained +PHP code to search the metadata directory for files beginning with `sp` or `idp` to assemble +the metadata. The format of these files differed from the standard SimpleSAMLphp metadata +files. + +Example: +```php +return [ + 'https://example.com' => [ + 'name' => ['en' => 'Example'], + // ... + ], +] +``` + +To use this old, non-standard file structure and format, add these two files to +your new image: + +saml20-idp-remote.php +```php + $value) { + $metadata[$key] = $value; +} +``` + +saml20-sp-remote.php +```php + $value) { + $metadata[$key] = $value; +} +``` + +#### Standard Metadata Format + +Moving forward, to utilize a multi-file approach while using the standard SimpleSAMLphp +metadata format, add these two files to your image: + +saml20-idp-remote.php +```php + Date: Tue, 30 Jul 2024 09:09:09 +0800 Subject: [PATCH 28/33] adjust test container metadata configuration to lack of default files --- .../{idp-remote.php => saml20-idp-remote.php} | 0 .../{sp-remote.php => saml20-sp-remote.php} | 0 docker-compose.yml | 14 ++++---------- 3 files changed, 4 insertions(+), 10 deletions(-) rename development/hub/metadata/{idp-remote.php => saml20-idp-remote.php} (100%) rename development/hub/metadata/{sp-remote.php => saml20-sp-remote.php} (100%) diff --git a/development/hub/metadata/idp-remote.php b/development/hub/metadata/saml20-idp-remote.php similarity index 100% rename from development/hub/metadata/idp-remote.php rename to development/hub/metadata/saml20-idp-remote.php diff --git a/development/hub/metadata/sp-remote.php b/development/hub/metadata/saml20-sp-remote.php similarity index 100% rename from development/hub/metadata/sp-remote.php rename to development/hub/metadata/saml20-sp-remote.php diff --git a/docker-compose.yml b/docker-compose.yml index 752cf38..1fa67a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -90,10 +90,7 @@ services: - ./development/announcement.php:/data/vendor/simplesamlphp/simplesamlphp/announcement/announcement.php # Utilize custom metadata - - ./development/hub/metadata/idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/idp-remote.php - - ./development/hub/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/hub/metadata/saml20-sp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-hosted.php - - ./development/hub/metadata/sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/sp-remote.php + - ./development/hub/metadata:/data/vendor/simplesamlphp/simplesamlphp/metadata # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -132,8 +129,7 @@ services: - ./development/logo_idp1.png:/data/vendor/simplesamlphp/simplesamlphp/public/logo.png # Utilize custom metadata - - ./development/idp-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/idp-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php + - ./development/idp-local/metadata:/data/vendor/simplesamlphp/simplesamlphp/metadata # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php @@ -196,8 +192,7 @@ services: - ./development/logo_idp2.png:/data/vendor/simplesamlphp/simplesamlphp/public/logo.png # Utilize custom metadata - - ./development/idp2-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/idp2-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php + - ./development/idp2-local/metadata:/data/vendor/simplesamlphp/simplesamlphp/metadata # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php @@ -240,8 +235,7 @@ services: - ./development/logo_idp3.png:/data/vendor/simplesamlphp/simplesamlphp/public/logo.png # Utilize custom metadata - - ./development/idp3-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/idp3-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php + - ./development/idp3-local/metadata:/data/vendor/simplesamlphp/simplesamlphp/metadata # Local modules - ./modules/mfa:/data/vendor/simplesamlphp/simplesamlphp/modules/mfa From 844f542144cb07f5652ee7e7963ec357abe01fd6 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:27:52 +0800 Subject: [PATCH 29/33] bypass ssp-base config.php for metadata "tests" --- tests/MetadataTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 15d0571..11b0a56 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use Sil\PhpEnv\Env; use Sil\SspUtils\Utils; +use SimpleSAML\Configuration; use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Module\sildisco\IdPDisco; @@ -25,6 +26,12 @@ class MetadataTest extends TestCase public $metadataPath = __DIR__ . '/../vendor/simplesamlphp/simplesamlphp/metadata'; + public static function setUpBeforeClass(): void + { + // use default configuration to bypass the ssp-base config file that has required environment variables + Configuration::setPreLoadedConfig(Configuration::loadFromArray([])); + } + public function testIDPRemoteMetadataIDPCode() { $metadata = MetaDataStorageHandler::getMetadataHandler(); From 9ee32d34bc8d909dd829eba686f301b9ec7d883a Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:36:24 +0800 Subject: [PATCH 30/33] enable sildisco module to gain access to getIdpsForSp method --- tests/MetadataTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 11b0a56..0eeca0a 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -28,8 +28,10 @@ class MetadataTest extends TestCase public static function setUpBeforeClass(): void { - // use default configuration to bypass the ssp-base config file that has required environment variables - Configuration::setPreLoadedConfig(Configuration::loadFromArray([])); + // override configuration to bypass the ssp-base config file that has required environment variables + Configuration::setPreLoadedConfig(Configuration::loadFromArray([ + 'module.enable' => ['sildisco' => true], // for IdPDisco::getIdpsForSp utility function + ])); } public function testIDPRemoteMetadataIDPCode() From 9b11d60d84ff0ba1d53f43c397604fe332a48c56 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:19:48 +0800 Subject: [PATCH 31/33] add an example of the "standard" metadata format [skip ci] --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 2641187..b3e1b26 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,14 @@ foreach ($startMetadata as $key => $value) { #### Standard Metadata Format +Example: +```php +$metadata['https://example.com'] = [ + 'name' => ['en' => 'Example'], + // ... +] +``` + Moving forward, to utilize a multi-file approach while using the standard SimpleSAMLphp metadata format, add these two files to your image: From a8e7d9f3abc31bfd01cf4c5d5890de037961bb22 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:40:11 +0800 Subject: [PATCH 32/33] PR feedback - use the correct variable Co-authored-by: forevermatt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3e1b26..8d84dc6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ will overwrite variables set in the execution environment. No metadata files are included by default. All metadata configuration must be provided by using ssp-base as a base image and adding files to the -`/data/vendor/simplesamlphp/simplesamlphp/metadata` directory. `SSP_BASE` is defined by +`/data/vendor/simplesamlphp/simplesamlphp/metadata` directory. `SSP_PATH` is defined by ssp-base as shorthand for `/data/vendor/simplesamlphp/simplesamlphp`. ```Dockerfile From c375cdc0a50f099fd24e10cb56be803183ff2504 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:07:04 +0800 Subject: [PATCH 33/33] remove unused SingleLogoutService.php override file --- .../ssp-overrides/SingleLogoutService.php | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 dockerbuild/ssp-overrides/SingleLogoutService.php diff --git a/dockerbuild/ssp-overrides/SingleLogoutService.php b/dockerbuild/ssp-overrides/SingleLogoutService.php deleted file mode 100644 index 711361a..0000000 --- a/dockerbuild/ssp-overrides/SingleLogoutService.php +++ /dev/null @@ -1,16 +0,0 @@ -