/** * Resolve the eduPersonTargetedId we should send. */ public function execute() { // Note that we try to service the final destination SP, if we know them and are allowed to do so. $destinationMetadata = EngineBlock_SamlHelper::getDestinationSpMetadata($this->_serviceProvider, $this->_request, $this->_server->getRepository()); // Resolve what NameID we should send the destination. $resolver = new EngineBlock_Saml2_NameIdResolver(); $nameId = $resolver->resolve($this->_request, $this->_response, $destinationMetadata, $this->_collabPersonId); // EPTID requires us to embed the <saml:NameID> element instead of just the value, so we generate that here. $document = new DOMDocument(); $document->loadXML('<base />'); SAML2_Utils::addNameId($document->documentElement, $nameId); // Add the eduPersonTargetedId attribute. $this->_responseAttributes['urn:mace:dir:attribute-def:eduPersonTargetedID'] = array($document->documentElement->childNodes); }
/** * Store a NameID to attribute. * * @param array &$state The request state. */ public function process(&$state) { assert('is_array($state)'); if (!isset($state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT])) { SimpleSAML\Logger::warning('Unable to generate eduPersonTargetedID because no persistent NameID was available.'); return; } $nameID = $state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT]; if ($this->nameId) { $doc = SAML2_DOMDocumentFactory::create(); $root = $doc->createElement('root'); $doc->appendChild($root); SAML2_Utils::addNameId($root, $nameID); $value = $doc->saveXML($root->firstChild); } else { $value = $nameID['Value']; } $state['Attributes'][$this->attribute] = array($value); }
/** * Get the NameID value. * * @return string|NULL The NameID value. */ protected function getValue(array &$state) { if (!isset($state['Destination']['entityid'])) { SimpleSAML_Logger::warning('No SP entity ID - not generating persistent NameID.'); return; } $spEntityId = $state['Destination']['entityid']; if (!isset($state['Source']['entityid'])) { SimpleSAML_Logger::warning('No IdP entity ID - not generating persistent NameID.'); return; } $idpEntityId = $state['Source']['entityid']; if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) { SimpleSAML_Logger::warning('Missing attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.'); return; } if (count($state['Attributes'][$this->attribute]) > 1) { SimpleSAML_Logger::warning('More than one value in attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.'); return; } $uid = array_values($state['Attributes'][$this->attribute]); /* Just in case the first index is no longer 0. */ $uid = $uid[0]; $secretSalt = SimpleSAML_Utilities::getSecretSalt(); $uidData = $spEntityId . '!' . $uid . '!' . $secretSalt; $uid = base64_encode(hash('sha1', $uidData, true)); // Convert the targeted ID to a SAML 2.0 name identifier element. $nameId = array('Format' => SAML2_Const::NAMEID_PERSISTENT, 'Value' => $uid); if (isset($state['Source']['entityid'])) { $nameId['NameQualifier'] = $state['Source']['entityid']; } if (isset($state['Destination']['entityid'])) { $nameId['SPNameQualifier'] = $state['Destination']['entityid']; } $doc = new DOMDocument(); $root = $doc->createElement('root'); $doc->appendChild($root); SAML2_Utils::addNameId($root, $nameId); $uid = $doc->saveXML($root->firstChild); $state['Attributes']['eduPersonTargetedID'] = array($uid); }
/** * Add a Subject-node to the assertion. * * @param DOMElement $root The assertion element we should add the subject to. */ private function addSubject(DOMElement $root) { if ($this->nameId === NULL && $this->encryptedNameId === NULL) { /* We don't have anything to create a Subject node for. */ return; } $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); if ($this->encryptedNameId === NULL) { SAML2_Utils::addNameId($subject, $this->nameId); } else { $eid = $subject->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:' . 'EncryptedID'); $subject->appendChild($eid); $eid->appendChild($subject->ownerDocument->importNode($this->encryptedNameId, TRUE)); } foreach ($this->SubjectConfirmation as $sc) { $sc->toXML($subject); } }
/** * Convert subject query message to an XML element. * * @return DOMElement This subject query. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); SAML2_Utils::addNameId($subject, $this->nameId); return $root; }
/** * Add a Subject-node to the assertion. * * @param DOMElement $root The assertion element we should add the subject to. */ protected function addSubject(DOMElement $root) { if ($this->nameId === NULL) { /* We don't have anything to create a Subject node for. */ return; } $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); SAML2_Utils::addNameId($subject, $this->nameId); if ($this->iterateSubjectConfirmationData) { $sc = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmation'); $subject->appendChild($sc); $sc->setAttribute('Method', SAML2_Const::CM_BEARER); if ($this->addSubjectConfirmationData) { foreach ($this->destination as $dest) { foreach ($this->subjectAddresses as $adr) { $scd = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmationData'); $sc->appendChild($scd); if ($this->notOnOrAfterSubjectConfirmationData !== NULL) { $scd->setAttribute('NotOnOrAfter', gmdate($this->dateformat, $this->notOnOrAfterSubjectConfirmationData)); } if ($dest !== NULL) { $scd->setAttribute('Recipient', $dest); } if ($this->inResponseTo !== NULL) { $scd->setAttribute('InResponseTo', $this->inResponseTo); } if (!empty($adr)) { $scd->setAttribute('Address', $adr); } } } } } else { if ($this->addSubjectConfirmationData) { foreach ($this->destination as $dest) { foreach ($this->subjectAddresses as $adr) { $sc = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmation'); $subject->appendChild($sc); $sc->setAttribute('Method', SAML2_Const::CM_BEARER); $scd = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmationData'); $sc->appendChild($scd); if ($this->notOnOrAfterSubjectConfirmationData !== NULL) { $scd->setAttribute('NotOnOrAfter', gmdate($this->dateformat, $this->notOnOrAfterSubjectConfirmationData)); } if ($dest !== NULL) { $scd->setAttribute('Recipient', $dest); } if ($this->inResponseTo !== NULL) { $scd->setAttribute('InResponseTo', $this->inResponseTo); } if (!empty($adr)) { $scd->setAttribute('Address', $adr); } } } } else { $sc = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmation'); $subject->appendChild($sc); $sc->setAttribute('Method', SAML2_Const::CM_BEARER); } } }
/** * Apply filter to add the targeted ID. * * @param array &$state The current state. */ public function process(&$state) { assert('is_array($state)'); assert('array_key_exists("Attributes", $state)'); if ($this->attribute === NULL) { if (!array_key_exists('UserID', $state)) { throw new Exception('core:TargetedID: Missing UserID for this user. Please' . ' check the \'userid.attribute\' option in the metadata against the' . ' attributes provided by the authentication source.'); } $userID = $state['UserID']; } else { if (!array_key_exists($this->attribute, $state['Attributes'])) { throw new Exception('core:TargetedID: Missing attribute \'' . $this->attribute . '\', which is needed to generate the targeted ID.'); } $userID = $state['Attributes'][$this->attribute][0]; } $secretSalt = SimpleSAML\Utils\Config::getSecretSalt(); if (array_key_exists('Source', $state)) { $srcID = self::getEntityId($state['Source']); } else { $srcID = ''; } if (array_key_exists('Destination', $state)) { $dstID = self::getEntityId($state['Destination']); } else { $dstID = ''; } $uidData = 'uidhashbase' . $secretSalt; $uidData .= strlen($srcID) . ':' . $srcID; $uidData .= strlen($dstID) . ':' . $dstID; $uidData .= strlen($userID) . ':' . $userID; $uidData .= $secretSalt; $uid = hash('sha1', $uidData); if ($this->generateNameId) { /* Convert the targeted ID to a SAML 2.0 name identifier element. */ $nameId = array('Format' => SAML2_Const::NAMEID_PERSISTENT, 'Value' => $uid); if (isset($state['Source']['entityid'])) { $nameId['NameQualifier'] = $state['Source']['entityid']; } if (isset($state['Destination']['entityid'])) { $nameId['SPNameQualifier'] = $state['Destination']['entityid']; } $doc = new DOMDocument(); $root = $doc->createElement('root'); $doc->appendChild($root); SAML2_Utils::addNameId($root, $nameId); $uid = $doc->saveXML($root->firstChild); } $state['Attributes']['eduPersonTargetedID'] = array($uid); }
/** * Convert this logout request message to an XML element. * * @return DOMElement This logout request. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); if ($this->notOnOrAfter !== NULL) { $root->setAttribute('NotOnOrAfter', gmdate('Y-m-d\\TH:i:s\\Z', $this->notOnOrAfter)); } if ($this->encryptedNameId === NULL) { SAML2_Utils::addNameId($root, $this->nameId); } else { $eid = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:' . 'EncryptedID'); $root->appendChild($eid); $eid->appendChild($root->ownerDocument->importNode($this->encryptedNameId, TRUE)); } foreach ($this->sessionIndexes as $sessionIndex) { SAML2_Utils::addString($root, SAML2_Const::NS_SAMLP, 'SessionIndex', $sessionIndex); } return $root; }
/** * Add a Subject-node to the assertion. * * @param DOMElement $root The assertion element we should add the subject to. */ private function addSubject(DOMElement $root) { // If there is no nameId (encrypted or not) there is nothing to create a subject for if ($this->nameId === NULL && $this->encryptedNameId === NULL) { return; } $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); if ($this->encryptedNameId === NULL) { SAML2_Utils::addNameId($subject, $this->nameId); } else { $eid = $subject->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:EncryptedID'); $eid->appendChild($subject->ownerDocument->importNode($this->encryptedNameId, TRUE)); $subject->appendChild($eid); } foreach ($this->subjectConfirmation as $sc) { $sc->toXML($subject); } }
/** * Convert this logout request message to an XML element. * * @return DOMElement This logout request. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); SAML2_Utils::addNameId($root, $this->nameId); if ($this->sessionIndex !== NULL) { if (is_array($this->sessionIndex)) { foreach ($this->sessionIndex as $si) { SAML2_Utils::addString($root, SAML2_Const::NS_SAMLP, 'SessionIndex', $si); } } elseif (is_string($this->sessionIndex)) { SAML2_Utils::addString($root, SAML2_Const::NS_SAMLP, 'SessionIndex', $this->sessionIndex); } } return $root; }
/** * Convert this logout request message to an XML element. * * @return DOMElement This logout request. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); SAML2_Utils::addNameId($root, $this->nameId); $root->setAttribute('NotOnOrAfter', gmdate('Y-m-d\\TH:i:s\\Z', time() + 3600)); if ($this->sessionIndex !== NULL) { if (is_array($this->sessionIndex)) { foreach ($this->sessionIndex as $si) { SAML2_Utils::addString($root, SAML2_Const::NS_SAMLP, 'SessionIndex', $si); } } elseif (is_string($this->sessionIndex)) { SAML2_Utils::addString($root, SAML2_Const::NS_SAMLP, 'SessionIndex', $this->sessionIndex); } } return $root; }
/** * Convert this logout request message to an XML element. * * @return DOMElement This logout request. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); SAML2_Utils::addNameId($root, $this->nameId); if ($this->sessionIndex !== NULL) { $sessionIndex = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'SessionIndex'); $sessionIndex->appendChild($this->document->createTextNode($this->sessionIndex)); $root->appendChild($sessionIndex); } return $root; }
/** * Add a Subject-node to the assertion. * * @param DOMElement $root The assertion element we should add the subject to. */ private function addSubject(DOMElement $root) { if ($this->nameId === NULL) { /* We don't have anything to create a Subject node for. */ return; } $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); SAML2_Utils::addNameId($subject, $this->nameId); foreach ($this->SubjectConfirmation as $sc) { $sc->toXML($subject); } }
/** * Convert the targeted ID to a SAML 2.0 name identifier element * * @param string $value The value of the attribute. * @param string $source Identifier of the IdP. * @param string $destination Identifier of the SP. * @return string The XML representing the element */ private static function toNameId($value, $source, $destination) { $nameId = array('Format' => SAML2_Const::NAMEID_PERSISTENT, 'Value' => $value); if (!empty($source)) { $nameId['NameQualifier'] = $source; } if (!empty($destination)) { $nameId['SPNameQualifier'] = $destination; } $doc = SAML2_DOMDocumentFactory::create(); $root = $doc->createElement('root'); $doc->appendChild($root); SAML2_Utils::addNameId($root, $nameId); return $doc->saveXML($root->firstChild); }
/** * Add a Subject-node to the assertion. * * @param DOMElement $root The assertion element we should add the subject to. */ private function addSubject(DOMElement $root) { if ($this->nameId === NULL) { /* We don't have anything to create a Subject node for. */ return; } $subject = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:Subject'); $root->appendChild($subject); SAML2_Utils::addNameId($subject, $this->nameId); $sc = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmation'); $subject->appendChild($sc); $sc->setAttribute('Method', SAML2_Const::CM_BEARER); $scd = $root->ownerDocument->createElementNS(SAML2_Const::NS_SAML, 'saml:SubjectConfirmationData'); $sc->appendChild($scd); if ($this->notOnOrAfter !== NULL) { $scd->setAttribute('NotOnOrAfter', gmdate('Y-m-d\\TH:i:s\\Z', $this->notOnOrAfter)); } if ($this->destination !== NULL) { $scd->setAttribute('Recipient', $this->destination); } if ($this->inResponseTo !== NULL) { $scd->setAttribute('InResponseTo', $this->inResponseTo); } }