From 361a41f028eaa8d9462322c6e0012ca928c38a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ou=C5=A1ek?= <melanger@users.noreply.github.com> Date: Tue, 15 Dec 2020 16:26:04 +0100 Subject: [PATCH] feat: allow EntityExtensions in IdP metadata --- docs/simplesamlphp-reference-idp-hosted.md | 41 +++++++++++++++++++ lib/SimpleSAML/Metadata/SAMLBuilder.php | 6 +++ .../SimpleSAML/Metadata/SAMLBuilderTest.php | 40 ++++++++++++++++++ www/saml2/idp/metadata.php | 4 ++ 4 files changed, 91 insertions(+) diff --git a/docs/simplesamlphp-reference-idp-hosted.md b/docs/simplesamlphp-reference-idp-hosted.md index 122814f7e..2730c1178 100644 --- a/docs/simplesamlphp-reference-idp-hosted.md +++ b/docs/simplesamlphp-reference-idp-hosted.md @@ -381,6 +381,10 @@ See the documentation for those extensions for more details: * [MDRPI extension](./simplesamlphp-metadata-extensions-rpi) * [EntityAttributes](./simplesamlphp-metadata-extensions-attributes) +For other metadata extensions, you can use the `saml:Extensions` option: + +`saml:Extensions` +: An array of `\SAML2\XML\Chunk`s to include in the IdP metadata extensions, at the same level as `EntityAttributes`. Examples -------- @@ -411,3 +415,40 @@ These are some examples of IdP metadata */ 'auth' => 'example-userpass', ]; + +### A custom metadata extension (eduGAIN republish request) ### + +``` +<?php + +$dom = \SAML2\DOMDocumentFactory::create(); +$republishRequest = $dom->createElementNS('http://eduid.cz/schema/metadata/1.0', 'eduidmd:RepublishRequest'); +$republishTarget = $dom->createElementNS('http://eduid.cz/schema/metadata/1.0', 'eduidmd:RepublishTarget', 'http://edugain.org/'); +$republishRequest->appendChild($republishTarget); +$ext = [new \SAML2\XML\Chunk($republishRequest)]; + +$metadata['__DYNAMIC:1__'] = [ + 'host' => '__DEFAULT__', + 'certificate' => 'example.org.crt', + 'privatekey' => 'example.org.pem', + 'auth' => 'example-userpass', + + /* + * The custom metadata extensions. + */ + 'saml:Extensions' => $ext, +]; +``` + +this generates the following metadata: + +``` +<EntityDescriptor entityID="..."> + <Extensions xmlns="urn:oasis:names:tc:SAML:2.0:metadata"> + <eduidmd:RepublishRequest xmlns:eduidmd="http://eduid.cz/schema/metadata/1.0"> + <eduidmd:RepublishTarget>http://edugain.org/</eduidmd:RepublishTarget> + </eduidmd:RepublishRequest> + </Extensions> + <!-- rest of metadata --> +</EntityDescriptor> +``` diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php index 47d873405..a41931cce 100644 --- a/lib/SimpleSAML/Metadata/SAMLBuilder.php +++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php @@ -225,6 +225,12 @@ class SAMLBuilder ); } + if ($metadata->hasValue('saml:Extensions')) { + $this->entityDescriptor->setExtensions( + array_merge($this->entityDescriptor->getExtensions(), $metadata->getArray('saml:Extensions')) + ); + } + if ($metadata->hasValue('RegistrationInfo')) { $ri = new RegistrationInfo(); foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) { diff --git a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php index 2998a753a..42e254619 100644 --- a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php +++ b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php @@ -240,4 +240,44 @@ class SAMLBuilderTest extends TestCase $entityDescriptorXml ); } + + /** + * Test custom metadata extension (saml:Extensions). + */ + public function testCustomMetadataExtension(): void + { + $entityId = 'https://entity.example.com/id'; + $set = 'saml20-idp-remote'; + + $dom = \SAML2\DOMDocumentFactory::create(); + $republishRequest = $dom->createElementNS( + 'http://eduid.cz/schema/metadata/1.0', + 'eduidmd:RepublishRequest' + ); + $republishTargetContent = 'http://edugain.org/'; + $republishTarget = $dom->createElementNS( + 'http://eduid.cz/schema/metadata/1.0', + 'eduidmd:RepublishTarget', + $republishTargetContent + ); + $republishRequest->appendChild($republishTarget); + $ext = [new \SAML2\XML\Chunk($republishRequest)]; + + $metadata = [ + 'entityid' => $entityId, + 'name' => ['en' => 'Test IdP'], + 'metadata-set' => $set, + 'saml:Extensions' => $ext, + ]; + + $samlBuilder = new SAMLBuilder($entityId); + $samlBuilder->addMetadata($set, $metadata); + + $idpDesc = $samlBuilder->getEntityDescriptor(); + $rt = $idpDesc->getElementsByTagNameNS('http://eduid.cz/schema/metadata/1.0', 'RepublishTarget'); + + /** @var \DOMElement $rt1 */ + $rt1 = $rt->item(0); + $this->assertEquals($republishTargetContent, $rt1->textContent); + } } diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php index 2f6807e8e..68404390f 100644 --- a/www/saml2/idp/metadata.php +++ b/www/saml2/idp/metadata.php @@ -173,6 +173,10 @@ try { } } + if ($idpmeta->hasValue('saml:Extensions')) { + $metaArray['saml:Extensions'] = $idpmeta->getArray('saml:Extensions'); + } + if ($idpmeta->hasValue('UIInfo')) { $metaArray['UIInfo'] = $idpmeta->getArray('UIInfo'); } -- GitLab