Skip to content

Commit 3de1258

Browse files
committed
Add support for setting the UserAttributes SAML Extension on the AuthnRequest with mail or SHO attributes from the SP form
1 parent 35b53d8 commit 3de1258

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

docker/sspwww/sp.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,61 @@
227227
}
228228
}
229229

230+
// SAML Extensions (email and SHO)
231+
if ( ( isset($_REQUEST['email_extension']) && strlen($_REQUEST['email_extension']) > 0 ) ||
232+
( isset($_REQUEST['sho_extension']) && strlen($_REQUEST['sho_extension']) > 0 ) )
233+
{
234+
$attributes = array(); // Array of attribute name => attribute value
235+
if ( isset($_REQUEST['email_extension']) && strlen($_REQUEST['email_extension']) > 0 ) {
236+
$attributes['urn:mace:dir:attribute-def:mail'] = $_REQUEST['email_extension'];
237+
}
238+
if ( isset($_REQUEST['sho_extension']) && strlen($_REQUEST['sho_extension']) > 0 ) {
239+
$attributes['urn:mace:terena.org:attribute-def:schacHomeOrganization'] = $_REQUEST['sho_extension'];
240+
}
241+
242+
// A DOMDocument to hold the DOM structure and to serve as a factory object for DOMElements
243+
// This is the method used in the Stepup-saml-bundle:
244+
// https://github.com/OpenConext/Stepup-saml-bundle/blob/main/src/SAML2/Extensions/GsspUserAttributesChunk.php
245+
// I'm not sure why this method is used over using new DOMElement() directly, and not using a DOMDocument at all
246+
$dom = new DOMDocument('1.0', 'UTF-8');
247+
248+
// Create the UserAttributes extension element
249+
$userAttributes = $dom->createElementNS('urn:mace:surf.nl:stepup:gssp-extensions', 'gssp:UserAttributes');
250+
$userAttributes->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
251+
$userAttributes->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
252+
253+
// Add the attributes to the extension
254+
foreach ($attributes as $attributeName => $attributeValue) {
255+
// Create the saml:Attribute element
256+
$attribute = $dom->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion', 'saml:Attribute');
257+
$attribute->setAttribute('NameFormat', 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri');
258+
$attribute->setAttribute('Name', $attributeName);
259+
260+
// Create the saml:AttributeValue element
261+
$attributeValue = $dom->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion', 'saml:AttributeValue', $attributeValue);
262+
$attributeValue->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi:type', 'xs:string');
263+
264+
// Append the saml:AttributeValue to saml:Attribute
265+
$attribute->appendChild($attributeValue);
266+
267+
// Append the saml:Attribute to gssp:UserAttributes
268+
$userAttributes->appendChild($attribute);
269+
}
270+
271+
// Append the root element to the document
272+
$dom->appendChild($userAttributes);
273+
274+
// Create a Chunk from the gssp:UserAttributes DOMElement
275+
$userAttributesChunk = new \SAML2\XML\Chunk($userAttributes);
276+
277+
// Add the gssp:UserAttributes to the SAML request
278+
// The SAML2 library uses the 'saml:Extensions' element to hold the extensions which is an array of
279+
// SAML2\XML\Chunk objects, one for each extension to add.
280+
// The SSP will then add the extensions to the SAML request by calling setExtensions(array $extensions) : void
281+
// on the SAML2\AuthnRequest object with the array of Chunk objects.
282+
$context['saml:Extensions'] = array($userAttributesChunk);
283+
}
284+
230285
// login
231286
$as->login( $context );
232287

@@ -263,6 +318,8 @@
263318
$ssobinding=htmlentities(isset($_REQUEST['ssobinding']) ? $_REQUEST['ssobinding'] : "");
264319
$requesterid=htmlentities(isset($_REQUEST['requesterid']) ? $_REQUEST['requesterid'] : "");
265320
$requesterid2=htmlentities(isset($_REQUEST['requesterid2']) ? $_REQUEST['requesterid2'] : "");
321+
$email_extension=htmlentities(isset($_REQUEST['email_extension']) ? $_REQUEST['email_extension'] : "");
322+
$sho_extension=htmlentities(isset($_REQUEST['sho_extension']) ? $_REQUEST['sho_extension'] : "");
266323
$scopingIDP=htmlentities(isset($_REQUEST['scopingIDP']) ? $_REQUEST['scopingIDP'] : "");
267324
$scopingIDP2=htmlentities(isset($_REQUEST['scopingIDP2']) ? $_REQUEST['scopingIDP2'] : "");
268325
$sp=htmlentities(isset($_REQUEST['sp']) ? $_REQUEST['sp'] : "default-sp");
@@ -560,6 +617,21 @@
560617
<label title="If selected two extra POST variables 'AuthMethod' and 'Context' are added to the AuthnRequest and the HTTP-POST binding is used. Note: Request LOA and Subject should be specified as well to make vailid SFO request to the Stepup-Gateway">Emulate SFO ADFS extension:</label><input type="checkbox" name="emulateadfs" value="true"{$emulateADFSchecked} /><br />
561618
</p>
562619
620+
<p>
621+
<label title="Specify an email address. If left blank the email extension is not added.">Email Userinfo extension:</label>
622+
<input id="email_extension" type="text" name="email_extension" value="{$email_extension}" size="80" /><br />
623+
<label title="Specify a domain. If left blank the schacHomeOranization extension is not added.">SHO Userinfo extension:</label>
624+
<input id="sho_extension" type="text" name="sho_extension" list="commonSHOs" value="{$sho_extension}" size="80" /><br />
625+
<datalist id="commonSHOs">
626+
<option value="institution-a.example.com" />
627+
<option value="institution-b.example.com" />
628+
<option value="institution-c.example.com" />
629+
<option value="institution-d.example.com" />
630+
<option value="Institution-D.EXAMPLE.COM" />
631+
<option value="institution-e.example.com" />
632+
<option value="institution-f.example.com" />
633+
</datalist>
634+
</p>
563635
<p>
564636
<button id="login_3" class="login" type="submit" name="action" value="login">Login</button>&nbsp;&nbsp;<button type="submit" name="action" value="reset">Reset</button><br />
565637
</p>

0 commit comments

Comments
 (0)