diff --git a/Dockerfile b/Dockerfile index 35a56acc..521727e8 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 8e768d15..3a91edea 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. @@ -31,14 +30,106 @@ 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_PATH` 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 + +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: + +saml20-idp-remote.php +```php + 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 @@ -164,11 +279,9 @@ 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', ], - + // ... ], @@ -181,12 +294,13 @@ 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 `loggerClass` parameter specifies the name of a PSR-3 compatible class that can be autoloaded, to use as the logger within ExpiryDate. @@ -200,46 +314,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 +358,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 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 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 +385,9 @@ Example (for `metadata/saml20-idp-hosted.php`): use Sil\PhpEnv\Env; use Sil\Psr3Adapters\Psr3SamlLogger; - + // ... - + 'authproc' => [ 10 => [ // Required: @@ -303,7 +403,7 @@ Example (for `metadata/saml20-idp-hosted.php`): // Optional: 'loggerClass' => Psr3SamlLogger::class, ], - + // ... ], @@ -312,7 +412,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 +427,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 +461,9 @@ Example (for `metadata/saml20-idp-hosted.php`): use Sil\PhpEnv\Env; use Sil\Psr3Adapters\Psr3SamlLogger; - + // ... - + 'authproc' => [ 10 => [ // Required: @@ -375,7 +475,7 @@ Example (for `metadata/saml20-idp-hosted.php`): // Optional: 'loggerClass' => Psr3SamlLogger::class, ], - + // ... ], @@ -397,8 +497,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 +564,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/behat.yml b/behat.yml index 0e4f8ffb..3f726202 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/development/hub/config/authsources.php b/development/hub/config/authsources.php index c3a20cbf..fe1b5130 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/hub/metadata/idp-remote.php b/development/hub/metadata/idp-remote.php deleted file mode 100644 index af01b351..00000000 --- a/development/hub/metadata/idp-remote.php +++ /dev/null @@ -1,133 +0,0 @@ - [ - '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==', - - // 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', - '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', - // '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'], - ], - - /* - * 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'], - ], - '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==', - ], - '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/saml20-idp-remote.php b/development/hub/metadata/saml20-idp-remote.php new file mode 100644 index 00000000..b9a56f9e --- /dev/null +++ b/development/hub/metadata/saml20-idp-remote.php @@ -0,0 +1,122 @@ + '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==', +]; +$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)', + + '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', + ], + '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 + */ +$metadata['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==', +]; +$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/saml20-sp-remote.php b/development/hub/metadata/saml20-sp-remote.php new file mode 100644 index 00000000..c8853ab0 --- /dev/null +++ b/development/hub/metadata/saml20-sp-remote.php @@ -0,0 +1,91 @@ + '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, +]; + +$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, +]; + +$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, +]; + +$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 + +$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, +]; + +$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/development/hub/metadata/sp-remote.php b/development/hub/metadata/sp-remote.php deleted file mode 100644 index 0bc515cf..00000000 --- a/development/hub/metadata/sp-remote.php +++ /dev/null @@ -1,93 +0,0 @@ - [ - '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, - ], - - '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, - ], - - // 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, - ], - - '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/development/idp-local/metadata/saml20-idp-hosted.php b/development/idp-local/metadata/saml20-idp-hosted.php index 796feea3..b59174ab 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/idp-local/metadata/saml20-sp-remote.php b/development/idp-local/metadata/saml20-sp-remote.php index 4720d9ad..7e46ff44 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/development/idp2-local/metadata/saml20-idp-hosted.php b/development/idp2-local/metadata/saml20-idp-hosted.php index 724dce30..60759f3f 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 2630be2c..3e684bd8 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 05bca64c..1fa67a98 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 @@ -91,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 @@ -111,7 +107,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" @@ -134,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 @@ -162,7 +156,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" @@ -182,6 +175,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: . @@ -198,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 @@ -217,7 +210,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" @@ -230,6 +222,7 @@ services: SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "red-teal" + HUB_MODE: "false" ssp-idp3.local: build: . @@ -242,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 @@ -261,8 +253,8 @@ services: SECRET_SALT: "h57fjem34fh*nsJFGNjweJ" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" - IDP_NAME: "IdP3" THEME_COLOR_SCHEME: "orange-light_blue" + HUB_MODE: "false" ssp-sp1.local: image: silintl/ssp-base:9.3.0 diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index db551f83..e93e1ec5 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'); @@ -54,18 +52,16 @@ $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); -$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', ''); $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'); @@ -78,22 +74,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, @@ -628,7 +614,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, @@ -671,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 @@ -909,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 /************************************* @@ -981,6 +966,11 @@ */ 'theme.controller' => MaterialController::class, + /* + * color scheme to use for the material theme + */ + 'theme.color-scheme' => $THEME_COLOR_SCHEME, + /* * Templating options * @@ -1043,12 +1033,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 | *********************/ diff --git a/dockerbuild/run-spidplinks.php b/dockerbuild/run-spidplinks.php index 82e3f723..2a6e0835 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/dockerbuild/ssp-overrides/SingleLogoutService.php b/dockerbuild/ssp-overrides/SingleLogoutService.php deleted file mode 100644 index 711361af..00000000 --- a/dockerbuild/ssp-overrides/SingleLogoutService.php +++ /dev/null @@ -1,16 +0,0 @@ - $value) { - $metadata[$key] = $value; -} diff --git a/dockerbuild/ssp-overrides/saml20-sp-remote.php b/dockerbuild/ssp-overrides/saml20-sp-remote.php deleted file mode 100644 index c9e9758c..00000000 --- a/dockerbuild/ssp-overrides/saml20-sp-remote.php +++ /dev/null @@ -1,11 +0,0 @@ - $value) { - $metadata[$key] = $value; -} diff --git a/docs/editing_authprocs.md b/docs/editing_authprocs.md index 88013fa8..2002dcca 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 e9bab580..5723bef2 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,9 @@ 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. - -##### 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. +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. ### 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/features/Sp1Idp2Sp2Sp3Idp1.feature b/features/Sp1Idp2Sp2Sp3Idp1.feature deleted file mode 100644 index fa32dcca..00000000 --- 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 26d54bc7..00000000 --- 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 7c73a543..00000000 --- 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 2db76fad..00000000 --- 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 aaf4ee9c..b0705fad 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." diff --git a/local.env.dist b/local.env.dist index a3a695eb..33da5ec0 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 @@ -10,7 +9,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= @@ -74,6 +72,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 diff --git a/modules/expirychecker/src/Auth/Process/ExpiryDate.php b/modules/expirychecker/src/Auth/Process/ExpiryDate.php index 3efd9e69..93f88a96 100644 --- a/modules/expirychecker/src/Auth/Process/ExpiryDate.php +++ b/modules/expirychecker/src/Auth/Process/ExpiryDate.php @@ -27,12 +27,10 @@ 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'; private string|null $expiryDateAttr = null; - private string $dateFormat = 'Y-m-d'; protected LoggerInterface $logger; @@ -54,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, @@ -70,10 +64,6 @@ public function __construct(array $config, mixed $reserved) Validator::STRING, Validator::NOT_EMPTY, ], - 'dateFormat' => [ - Validator::STRING, - Validator::NOT_EMPTY, - ], ]); } @@ -359,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'); @@ -394,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 871d3884..d013ee40 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. diff --git a/modules/mfa/public/new-backup-codes.php b/modules/mfa/public/new-backup-codes.php index 67e61fef..539604f6 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 f3cde9a8..f3b05bf6 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 12fc066f..6192b8c9 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 diff --git a/modules/sildisco/src/Auth/Process/AddIdp2NameId.php b/modules/sildisco/src/Auth/Process/AddIdp2NameId.php index 1ec92324..b41f01cc 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 c13f1c17..6d59643b 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 354244b0..791d76aa 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/src/IdPDisco.php b/modules/sildisco/src/IdPDisco.php index f32e6069..97eccd86 100644 --- a/modules/sildisco/src/IdPDisco.php +++ b/modules/sildisco/src/IdPDisco.php @@ -3,13 +3,16 @@ 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; +use yii\db\Exception; /** * This class implements a custom IdP discovery service, for use with a ssp hub (proxy) @@ -33,12 +36,10 @@ 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 + */ private function getSPEntityIDAndReducedIdpList(): array { @@ -50,18 +51,18 @@ 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 = self::getReducedIdpList($idpList, $spEntityId); + return array($spEntityId, $idpList); } @@ -92,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'); @@ -154,4 +154,56 @@ 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; + } + + /** + * 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/modules/sildisco/tests/AddIdpTest.php b/modules/sildisco/tests/AddIdpTest.php index 686eb07e..5f99bfdb 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 c54b8c0a..c24f7357 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 00000000..950a88ce --- /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 8df2684c..00000000 --- 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 b5a47975..00000000 --- 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 4cafa7c8..00000000 --- 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 00000000..5c76c187 --- /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', +]; diff --git a/package-lock.json b/package-lock.json index e8abf91e..f030bee5 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 aca8b163..d3856add 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "simplesamlphp-module-material", + "name": "ssp-base", "dependencies": { "@simplewebauthn/browser": "^4.1.0" } diff --git a/tests/AnnouncementTest.php b/tests/AnnouncementTest.php index f181cda4..43344996 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)) { + $results = AnnouncementUtils::getSimpleAnnouncement(); + $this->assertNotNull($results); + } } } \ No newline at end of file diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 4786677c..68f890cc 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -6,9 +6,10 @@ use PHPUnit\Framework\TestCase; use Sil\PhpEnv\Env; -use Sil\SspUtils\DiscoUtils; -use Sil\SspUtils\Metadata; use Sil\SspUtils\Utils; +use SimpleSAML\Configuration; +use SimpleSAML\Metadata\MetaDataStorageHandler; +use SimpleSAML\Module\sildisco\IdPDisco; class MetadataTest extends TestCase { @@ -25,56 +26,25 @@ class MetadataTest extends TestCase public $metadataPath = __DIR__ . '/../vendor/simplesamlphp/simplesamlphp/metadata'; - public function testLintTestMetadataFiles() + public static function setUpBeforeClass(): void { - $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); - } + // 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() { - $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 ' . '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, ' . @@ -92,7 +62,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) { @@ -101,7 +72,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)); @@ -117,7 +88,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])) { @@ -125,7 +97,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)); @@ -140,11 +112,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) { @@ -157,7 +130,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)); @@ -166,12 +139,13 @@ public function testIDPRemoteMetadataBadSPListEntry() public function testIDPRemoteMetadataNoDuplicateIDPCode() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $codes = []; 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; } @@ -179,29 +153,18 @@ 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->assertNotContains($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->assertNotContains($entityId, $entities, 'Duplicate IdP entityId found: ' . $entityId); + $entities[] = $entityId; } } @@ -213,28 +176,27 @@ public function testMetadataNoSpsWithoutAnIdp() return; } - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; foreach ($spEntries as $spEntityId => $spEntry) { - $results = DiscoUtils::getIdpsForSp( - $spEntityId, - $this->metadataPath - ); + $results = IdPDisco::getIdpsForSp($spEntityId); if (empty($results)) { $badSps[] = $spEntityId; } } - $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)); } public function testMetadataBadIdpName() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $badNames = []; @@ -244,14 +206,15 @@ 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)); } public function testMetadataMissingLogoURL() { - $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $idpEntries = $metadata->getList(); $badLogos = []; @@ -261,7 +224,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)); } @@ -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 = []; @@ -288,7 +252,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)); } @@ -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 = []; @@ -311,7 +276,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)); } @@ -324,7 +289,8 @@ public function testMetadataSPWithNoName() return; } - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -334,14 +300,15 @@ 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)); } public function testMetadataCerts() { - $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); + $metadata = MetaDataStorageHandler::getMetadataHandler(); + $spEntries = $metadata->getList('saml20-sp-remote'); $badSps = []; @@ -356,7 +323,7 @@ public function testMetadataCerts() } } - $this->assertTrue(empty($badSps), + $this->assertEmpty($badSps, 'At least one SP has no certData entry ... ' . var_export($badSps, True)); @@ -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 = []; @@ -382,7 +350,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)); @@ -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 = []; @@ -412,7 +381,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)); @@ -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 = []; @@ -441,7 +411,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)); @@ -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); - } }