Skip to content
Snippets Groups Projects
Commit 132a0dd2 authored by Jaime Pérez Crespo's avatar Jaime Pérez Crespo
Browse files

Support for UIInfo elements in SP metadata. Bugfix with SP metadata signing.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3226 44740490-163a-0410-bde0-09ae8108e29a
parent d0963278
No related branches found
No related tags found
No related merge requests found
...@@ -318,6 +318,8 @@ class SimpleSAML_Metadata_SAMLBuilder { ...@@ -318,6 +318,8 @@ class SimpleSAML_Metadata_SAMLBuilder {
return; return;
} }
$attributesrequired = $metadata->getArray('attributes.required', array());
/* /*
* Add an AttributeConsumingService element with information as name and description and list * Add an AttributeConsumingService element with information as name and description and list
* of requested attributes * of requested attributes
...@@ -336,6 +338,9 @@ class SimpleSAML_Metadata_SAMLBuilder { ...@@ -336,6 +338,9 @@ class SimpleSAML_Metadata_SAMLBuilder {
if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) { if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
$t->NameFormat = $nameFormat; $t->NameFormat = $nameFormat;
} }
if (in_array($attribute, $attributesrequired)) {
$t->isRequired = true;
}
$attributeconsumer->RequestedAttribute[] = $t; $attributeconsumer->RequestedAttribute[] = $t;
} }
...@@ -383,16 +388,18 @@ class SimpleSAML_Metadata_SAMLBuilder { ...@@ -383,16 +388,18 @@ class SimpleSAML_Metadata_SAMLBuilder {
* Add SAML 2.0 SP metadata. * Add SAML 2.0 SP metadata.
* *
* @param array $metadata The metadata. * @param array $metadata The metadata.
* @param array $protocols The protocols supported.
*/ */
public function addMetadataSP20($metadata) { public function addMetadataSP20($metadata, $protocols = array(SAML2_Const::NS_SAMLP)) {
assert('is_array($metadata)'); assert('is_array($metadata)');
assert('is_array($protocols)');
assert('isset($metadata["entityid"])'); assert('isset($metadata["entityid"])');
assert('isset($metadata["metadata-set"])'); assert('isset($metadata["metadata-set"])');
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']); $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
$e = new SAML2_XML_md_SPSSODescriptor(); $e = new SAML2_XML_md_SPSSODescriptor();
$e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:2.0:protocol'; $e->protocolSupportEnumeration = $protocols;
$this->addExtensions($metadata, $e); $this->addExtensions($metadata, $e);
......
...@@ -19,32 +19,22 @@ $entityId = $source->getEntityId(); ...@@ -19,32 +19,22 @@ $entityId = $source->getEntityId();
$spconfig = $source->getMetadata(); $spconfig = $source->getMetadata();
$metaArray20 = array( $metaArray20 = array(
'AssertionConsumerService' => SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId),
'SingleLogoutService' => SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId), 'SingleLogoutService' => SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId),
); );
$ed = new SAML2_XML_md_EntityDescriptor();
$ed->entityID = $entityId;
$sp = new SAML2_XML_md_SPSSODescriptor();
$ed->RoleDescriptor[] = $sp;
$sp->protocolSupportEnumeration = array(
'urn:oasis:names:tc:SAML:1.1:protocol',
'urn:oasis:names:tc:SAML:2.0:protocol'
);
$slo = new SAML2_XML_md_EndpointType();
$slo->Binding = SAML2_Const::BINDING_HTTP_REDIRECT;
$slo->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId);
$sp->SingleLogoutService[] = $slo;
$store = SimpleSAML_Store::getInstance(); $store = SimpleSAML_Store::getInstance();
if ($store instanceof SimpleSAML_Store_SQL) { if ($store instanceof SimpleSAML_Store_SQL) {
/* We can properly support SOAP logout. */ /* We can properly support SOAP logout. */
$slo = new SAML2_XML_md_EndpointType(); $metaArray20['SingleLogoutService'] = array(
$slo->Binding = SAML2_Const::BINDING_SOAP; array(
$slo->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId); 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
$sp->SingleLogoutService[] = $slo; 'Location' => SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId),
),
array(
'Binding' => SAML2_Const::BINDING_SOAP,
'Location' => SimpleSAML_Module::getModuleURL('saml/sp/saml2-logout.php/' . $sourceId),
),
);
} }
$assertionsconsumerservicesdefault = array( $assertionsconsumerservicesdefault = array(
...@@ -54,44 +44,45 @@ $assertionsconsumerservicesdefault = array( ...@@ -54,44 +44,45 @@ $assertionsconsumerservicesdefault = array(
'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01', 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01',
); );
if ($spconfig->getBoolean('saml20.hok.assertion', FALSE)) { if ($spconfig->getString('ProtocolBinding', '') == 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser') {
$assertionsconsumerservicesdefault[] = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser'; $assertionsconsumerservicesdefault[] = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser';
} }
$assertionsconsumerservices = $spconfig->getArray('acs.Bindings', $assertionsconsumerservicesdefault); $assertionsconsumerservices = $spconfig->getArray('acs.Bindings', $assertionsconsumerservicesdefault);
$index = 0; $index = 0;
$eps = array();
foreach ($assertionsconsumerservices as $services) { foreach ($assertionsconsumerservices as $services) {
$acs = new SAML2_XML_md_IndexedEndpointType(); $acsArray = array('index' => $index);
$acs->index = $index;
switch ($services) { switch ($services) {
case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST': case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST':
$acs->Binding = SAML2_Const::BINDING_HTTP_POST; $acsArray['Binding'] = SAML2_Const::BINDING_HTTP_POST;
$acs->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId); $acsArray['Location'] = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId);
break; break;
case 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post': case 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post':
$acs->Binding = 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post'; $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post';
$acs->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $sourceId); $acsArray['Location'] = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $sourceId);
break; break;
case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact': case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact':
$acs->Binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'; $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact';
$acs->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId); $acsArray['Location'] = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId);
break; break;
case 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01': case 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01':
$acs->Binding = 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01'; $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01';
$acs->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $sourceId . '/artifact'); $acsArray['Location'] = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $sourceId . '/artifact');
break; break;
case 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser': case 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser':
$acs->Binding = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser'; $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser';
$acs->setAttributeNS(SAML2_Const::NS_HOK, 'hoksso:ProtocolBinding', SAML2_Const::BINDING_HTTP_POST); $acsArray['Location'] = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId);
$acs->Location = SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $sourceId); $acsArray['hoksso:ProtocolBinding'] = SAML2_Const::BINDING_HTTP_REDIRECT;
break; break;
} }
$sp->AssertionConsumerService[] = $acs; $eps[] = $acsArray;
$index++; $index++;
} }
$metaArray20['AssertionConsumerService'] = $eps;
$keys = array(); $keys = array();
$certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig, FALSE, 'new_'); $certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig, FALSE, 'new_');
...@@ -99,13 +90,6 @@ if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) { ...@@ -99,13 +90,6 @@ if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) {
$hasNewCert = TRUE; $hasNewCert = TRUE;
$certData = $certInfo['certData']; $certData = $certInfo['certData'];
$kd = SAML2_Utils::createKeyDescriptor($certData);
$kd->use = 'signing';
$sp->KeyDescriptor[] = $kd;
$kd = SAML2_Utils::createKeyDescriptor($certData);
$kd->use = 'encryption';
$sp->KeyDescriptor[] = $kd;
$keys[] = array( $keys[] = array(
'type' => 'X509Certificate', 'type' => 'X509Certificate',
...@@ -120,16 +104,6 @@ if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) { ...@@ -120,16 +104,6 @@ if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) {
$certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig); $certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig);
if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) { if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) {
$certData = $certInfo['certData']; $certData = $certInfo['certData'];
$kd = SAML2_Utils::createKeyDescriptor($certData);
$kd->use = 'signing';
$sp->KeyDescriptor[] = $kd;
if (!$hasNewCert) {
/* Don't include the old certificate for encryption when we have a newer certificate. */
$kd = SAML2_Utils::createKeyDescriptor($certData);
$kd->use = 'encryption';
$sp->KeyDescriptor[] = $kd;
}
$keys[] = array( $keys[] = array(
'type' => 'X509Certificate', 'type' => 'X509Certificate',
...@@ -148,18 +122,6 @@ if ($name !== NULL && !empty($attributes)) { ...@@ -148,18 +122,6 @@ if ($name !== NULL && !empty($attributes)) {
$attributesrequired = $spconfig->getArray('attributes.required', array()); $attributesrequired = $spconfig->getArray('attributes.required', array());
/* We have everything necessary to add an AttributeConsumingService. */
$acs = new SAML2_XML_md_AttributeConsumingService();
$sp->AttributeConsumingService[] = $acs;
$acs->index = 0;
$acs->ServiceName = $name;
$description = $spconfig->getLocalizedString('description', NULL);
if ($description !== NULL) {
$acs->ServiceDescription = $description;
}
$nameFormat = $spconfig->getString('attributes.NameFormat', NULL); $nameFormat = $spconfig->getString('attributes.NameFormat', NULL);
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$a = new SAML2_XML_md_RequestedAttribute(); $a = new SAML2_XML_md_RequestedAttribute();
...@@ -169,9 +131,10 @@ if ($name !== NULL && !empty($attributes)) { ...@@ -169,9 +131,10 @@ if ($name !== NULL && !empty($attributes)) {
if (in_array($attribute, $attributesrequired)) if (in_array($attribute, $attributesrequired))
$a->isRequired = true; $a->isRequired = true;
$acs->RequestedAttribute[] = $a;
} }
$metaArray20['attributes.required'] = $attributesrequired;
$metaArray20['name'] = $name; $metaArray20['name'] = $name;
if ($description !== NULL) { if ($description !== NULL) {
$metaArray20['description'] = $description; $metaArray20['description'] = $description;
...@@ -183,63 +146,70 @@ if ($name !== NULL && !empty($attributes)) { ...@@ -183,63 +146,70 @@ if ($name !== NULL && !empty($attributes)) {
} }
} }
// add organization info
$orgName = $spconfig->getLocalizedString('OrganizationName', NULL); $orgName = $spconfig->getLocalizedString('OrganizationName', NULL);
if ($orgName !== NULL) { if ($orgName !== NULL) {
$o = new SAML2_XML_md_Organization(); $metaArray20['OrganizationName'] = $orgName;
$o->OrganizationName = $orgName;
$o->OrganizationDisplayName = $spconfig->getLocalizedString('OrganizationDisplayName', NULL); $metaArray20['OrganizationDisplayName'] = $spconfig->getLocalizedString('OrganizationDisplayName', NULL);
if ($o->OrganizationDisplayName === NULL) { if ($metaArray20['OrganizationDisplayName'] === NULL) {
$o->OrganizationDisplayName = $orgName; $metaArray20['OrganizationDisplayName'] = $orgName;
} }
$o->OrganizationURL = $spconfig->getLocalizedString('OrganizationURL', NULL); $metaArray20['OrganizationURL'] = $spconfig->getLocalizedString('OrganizationURL', NULL);
if ($o->OrganizationURL === NULL) { if ($metaArray20['OrganizationURL'] === NULL) {
throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.'); throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
} }
$ed->Organization = $o;
$metaArray20['OrganizationName'] = $orgName;
$metaArray20['OrganizationDisplayName'] = $o->OrganizationDisplayName;
$metaArray20['OrganizationURL'] = $o->OrganizationURL;
} }
$c = new SAML2_XML_md_ContactPerson(); // add technical contact
$c->contactType = 'technical';
$email = $config->getString('technicalcontact_email', NULL); $email = $config->getString('technicalcontact_email', NULL);
if ($email !== NULL) { $contact = array('emailAddress' => $email);
$c->EmailAddress = array($email);
}
$name = $config->getString('technicalcontact_name', NULL); $name = $config->getString('technicalcontact_name', NULL);
if ($name === NULL) { if ($name === NULL) {
/* Nothing to do here... */ /* Nothing to do here... */
} elseif (preg_match('@^(.*?)\s*,\s*(.*)$@D', $name, $matches)) { } elseif (preg_match('@^(.*?)\s*,\s*(.*)$@D', $name, $matches)) {
$c->SurName = $matches[1]; $contact['surName'] = $matches[1];
$c->GivenName = $matches[2]; $contact['givenName'] = $matches[2];
} elseif (preg_match('@^(.*?)\s+(.*)$@D', $name, $matches)) { } elseif (preg_match('@^(.*?)\s+(.*)$@D', $name, $matches)) {
$c->GivenName = $matches[1]; $contact['givenName'] = $matches[1];
$c->SurName = $matches[2]; $contact['surName'] = $matches[2];
} else { } else {
$c->GivenName = $name; $contact['givenName'] = $name;
} }
$ed->ContactPerson[] = $c;
$xml = $ed->toXML();
SimpleSAML_Utilities::formatDOMElement($xml);
$xml = $xml->ownerDocument->saveXML($xml);
// add certificate
if (count($keys) === 1) { if (count($keys) === 1) {
$metaArray20['certData'] = $keys[0]['X509Certificate']; $metaArray20['certData'] = $keys[0]['X509Certificate'];
} elseif (count($keys) > 1) { } elseif (count($keys) > 1) {
$metaArray20['keys'] = $keys; $metaArray20['keys'] = $keys;
} }
// add UIInfo extension
if ($spconfig->hasValue('UIInfo')) {
$metaArray20['UIInfo'] = $spconfig->getArray('UIInfo');
}
$supported_protocols = array('urn:oasis:names:tc:SAML:1.1:protocol', SAML2_Const::NS_SAMLP);
$metaArray20['metadata-set'] = 'saml20-sp-remote';
$metaArray20['entityid'] = $entityId;
$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
$metaBuilder->addMetadataSP20($metaArray20, $supported_protocols);
$metaBuilder->addOrganizationInfo($metaArray20);
$metaBuilder->addContact('technical', $contact);
$xml = $metaBuilder->getEntityDescriptorText();
unset($metaArray20['attributes.required']);
unset($metaArray20['UIInfo']);
unset($metaArray20['metadata-set']);
unset($metaArray20['entityid']);
/* Sign the metadata if enabled. */ /* Sign the metadata if enabled. */
$xml = SimpleSAML_Metadata_Signer::sign($xml, $sp, 'SAML 2 SP'); $xml = SimpleSAML_Metadata_Signer::sign($xml, $spconfig->toArray(), 'SAML 2 SP');
if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] == 'xhtml') { if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] == 'xhtml') {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment