Skip to content

Commit 87ca004

Browse files
authored
Merge pull request SAML-Toolkits#161 from talkspiritlab/master
Add saml attributes in metadata
2 parents 1365fe5 + 676c27c commit 87ca004

File tree

3 files changed

+138
-3
lines changed

3 files changed

+138
-3
lines changed

lib/Saml2/Metadata.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
2-
2+
33
/**
44
* Metadata lib of OneLogin PHP Toolkit
55
*
@@ -58,6 +58,7 @@ public static function builder($sp, $authnsign = false, $wsign = false, $validUn
5858
}
5959

6060
$strOrganization = '';
61+
6162
if (!empty($organization)) {
6263
$organizationInfoNames = array();
6364
$organizationInfoDisplaynames = array();
@@ -96,6 +97,42 @@ public static function builder($sp, $authnsign = false, $wsign = false, $validUn
9697
$strContacts = "\n".implode("\n", $contactsInfo);
9798
}
9899

100+
$strAttributeConsumingService = '';
101+
if (isset($sp['attributeConsumingService'])) {
102+
$attrCsDesc = '';
103+
if (isset($sp['attributeConsumingService']['serviceDescription'])) {
104+
$attrCsDesc = sprintf(
105+
' <md:ServiceDescription xml:lang="en">%s</md:ServiceDescription>' . PHP_EOL,
106+
$sp['attributeConsumingService']['serviceDescription']
107+
);
108+
}
109+
if (!isset($sp['attributeConsumingService']['serviceName'])) {
110+
$sp['attributeConsumingService']['serviceName'] = 'Service';
111+
}
112+
$requestedAttributeData = array();
113+
foreach ($sp['attributeConsumingService']['requestedAttributes'] as $attribute) {
114+
$requestedAttributeStr = sprintf(' <md:RequestedAttribute Name="%s"', $attribute['name']);
115+
if (isset($attribute['nameFormat'])) {
116+
$requestedAttributeStr .= sprintf(' NameFormat="%s"', $attribute['nameFormat']);
117+
}
118+
if (isset($attribute['friendlyName'])) {
119+
$requestedAttributeStr .= sprintf(' FriendlyName="%s"', $attribute['friendlyName']);
120+
}
121+
if (isset($attribute['isRequired'])) {
122+
$requestedAttributeStr .= sprintf(' isRequired="%s"', $attribute['isRequired'] === true ? 'true' : 'false');
123+
}
124+
$requestedAttributeData[] = $requestedAttributeStr . '/>';
125+
}
126+
127+
$requestedAttributeStr = implode(PHP_EOL, $requestedAttributeData);
128+
$strAttributeConsumingService = <<<METADATA_TEMPLATE
129+
<md:AttributeConsumingService index="1">
130+
<md:ServiceName xml:lang="en">{$sp['attributeConsumingService']['serviceName']}</md:ServiceName>
131+
{$attrCsDesc}{$requestedAttributeStr}
132+
</md:AttributeConsumingService>
133+
METADATA_TEMPLATE;
134+
}
135+
99136
$metadata = <<<METADATA_TEMPLATE
100137
<?xml version="1.0"?>
101138
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
@@ -107,6 +144,7 @@ public static function builder($sp, $authnsign = false, $wsign = false, $validUn
107144
<md:AssertionConsumerService Binding="{$sp['assertionConsumerService']['binding']}"
108145
Location="{$sp['assertionConsumerService']['url']}"
109146
index="1" />
147+
{$strAttributeConsumingService}
110148
</md:SPSSODescriptor>{$strOrganization}{$strContacts}
111149
</md:EntityDescriptor>
112150
METADATA_TEMPLATE;
@@ -159,7 +197,7 @@ public static function addX509KeyDescriptors($metadata, $cert, $wantsEncrypted =
159197

160198
$keyInfo = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'ds:KeyInfo');
161199
$keyInfo->appendChild($keyData);
162-
200+
163201
$keyDescriptor = $xml->createElementNS(OneLogin_Saml2_Constants::NS_MD, "md:KeyDescriptor");
164202

165203
$SPSSODescriptor = $xml->getElementsByTagName('SPSSODescriptor')->item(0);

tests/settings/settings3.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
$settingsInfo = array (
3+
'strict' => false,
4+
'debug' => false,
5+
'sp' => array (
6+
'entityId' => 'http://stuff.com/endpoints/metadata.php',
7+
'assertionConsumerService' => array (
8+
'url' => 'http://stuff.com/endpoints/endpoints/acs.php',
9+
),
10+
'singleLogoutService' => array (
11+
'url' => 'http://stuff.com/endpoints/endpoints/sls.php',
12+
),
13+
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
14+
'attributeConsumingService' => array (
15+
'serviceName' => 'Service Name',
16+
'serviceDescription' => 'Service Description',
17+
'requestedAttributes' => array (
18+
array (
19+
'nameFormat' => \OneLogin_Saml2_Constants::ATTRNAME_FORMAT_URI,
20+
'isRequired' => true,
21+
'name' => 'Email',
22+
'friendlyName' => 'Email'
23+
),
24+
array (
25+
'nameFormat' => \OneLogin_Saml2_Constants::ATTRNAME_FORMAT_URI,
26+
'isRequired' => true,
27+
'name' => 'FirstName'
28+
),
29+
array (
30+
'nameFormat' => \OneLogin_Saml2_Constants::ATTRNAME_FORMAT_URI,
31+
'isRequired' => true,
32+
'name' => 'LastName',
33+
),
34+
)
35+
)
36+
),
37+
'idp' => array (
38+
'entityId' => 'http://idp.example.com/',
39+
'singleSignOnService' => array (
40+
'url' => 'http://idp.example.com/SSOService.php',
41+
),
42+
'singleLogoutService' => array (
43+
'url' => 'http://idp.example.com/SingleLogoutService.php',
44+
),
45+
'x509cert' => 'MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo',
46+
),
47+
48+
'security' => array (
49+
'authnRequestsSigned' => false,
50+
'wantAssertionsSigned' => false,
51+
'signMetadata' => false,
52+
),
53+
'contactPerson' => array (
54+
'technical' => array (
55+
'givenName' => 'technical_name',
56+
'emailAddress' => '[email protected]',
57+
),
58+
'support' => array (
59+
'givenName' => 'support_name',
60+
'emailAddress' => '[email protected]',
61+
),
62+
),
63+
64+
'organization' => array (
65+
'en-US' => array(
66+
'name' => 'sp_test',
67+
'displayname' => 'SP test',
68+
'url' => 'http://sp.example.com',
69+
),
70+
),
71+
);

tests/src/OneLogin/Saml2/MetadataTest.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ public function testBuilder()
5757
$this->assertNotContains(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', $metadata2);
5858
}
5959

60+
/**
61+
* Tests the builder method of the OneLogin_Saml2_Metadata
62+
*
63+
* @covers OneLogin_Saml2_Metadata::builder
64+
*/
65+
public function testBuilderWithAttributeConsumingService()
66+
{
67+
$settingsDir = TEST_ROOT .'/settings/';
68+
include $settingsDir.'settings3.php';
69+
$settings = new OneLogin_Saml2_Settings($settingsInfo);
70+
$spData = $settings->getSPData();
71+
$security = $settings->getSecurityData();
72+
$organization = $settings->getOrganization();
73+
$contacts = $settings->getContacts();
74+
75+
$metadata = OneLogin_Saml2_Metadata::builder($spData, $security['authnRequestsSigned'], $security['wantAssertionsSigned'], null, null, $contacts, $organization);
76+
77+
$this->assertContains('<md:ServiceName xml:lang="en">Service Name</md:ServiceName>', $metadata);
78+
$this->assertContains('<md:ServiceDescription xml:lang="en">Service Description</md:ServiceDescription>', $metadata);
79+
$this->assertContains('<md:RequestedAttribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>', $metadata);
80+
$this->assertContains('<md:RequestedAttribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>', $metadata);
81+
82+
$result = \OneLogin_Saml2_Utils::validateXML($metadata, 'saml-schema-metadata-2.0.xsd');
83+
$this->assertInstanceOf('DOMDocument', $result);
84+
}
85+
6086
/**
6187
* Tests the signMetadata method of the OneLogin_Saml2_Metadata
6288
*
@@ -90,7 +116,7 @@ public function testSignMetadata()
90116
$this->assertContains('Location="http://stuff.com/endpoints/endpoints/acs.php"', $signedMetadata);
91117
$this->assertContains('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', $signedMetadata);
92118
$this->assertContains(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', $signedMetadata);
93-
119+
94120
$this->assertContains('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', $signedMetadata);
95121

96122
$this->assertContains('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', $signedMetadata);

0 commit comments

Comments
 (0)