Build a logout response based on information in the metadata.
public static buildLogoutResponse ( SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata ) | ||
$srcMetadata | SimpleSAML_Configuration | The metadata of the sender. |
$dstMetadata | SimpleSAML_Configuration |
protected function createLogoutResponse($testrun, $logoutRequest, $logoutRelayState) { $this->log($testrun, 'Creating response with relaystate [' . $logoutRelayState . ']'); $idpMetadata = SimpleSAML_Configuration::loadFromArray($this->idpmetadata); $spMetadata = SimpleSAML_Configuration::loadFromArray($this->metadata); // Get SingleLogoutService URL $consumerURLf = $spMetadata->getDefaultEndpoint('SingleLogoutService', array('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect')); $consumerURL = $consumerURLf['Location']; /* Create and send response. */ $response = sspmod_saml_Message::buildLogoutResponse($idpMetadata, $spMetadata); # $response->setRelayState($logoutRequest->getRelayState()); error_log(var_export($logoutRequest, TRUE)); $response->setInResponseTo($logoutRequest->getId()); $keyArray = SimpleSAML_Utilities::loadPrivateKey($idpMetadata, TRUE); $certArray = SimpleSAML_Utilities::loadPublicKey($idpMetadata, FALSE); $privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $privateKey->loadKey($keyArray['PEM'], FALSE); $response->setSignatureKey($privateKey); if ($certArray === NULL) { throw new Exception('No certificates found. [1]'); } if (!array_key_exists('PEM', $certArray)) { throw new Exception('No certificates found. [2]'); } $response->setCertificates(array($certArray['PEM'])); $msgStr = $response->toUnsignedXML(); #$this->tweakResponseDOM($testrun, $msgStr); $msgStr = $msgStr->ownerDocument->saveXML($msgStr); # echo '<pre>'; echo(htmlspecialchars($msgStr)); exit; # $msgStr = base64_encode($msgStr); # $msgStr = htmlspecialchars($msgStr); return array('url' => $consumerURL, 'Response' => $msgStr, 'ResponseObj' => $response, 'RelayState' => $logoutRelayState); }
foreach ($keys as $i => $key) { try { $message->decryptNameId($key); SimpleSAML_Logger::debug('Decryption with key #' . $i . ' succeeded.'); } catch (Exception $e) { SimpleSAML_Logger::debug('Decryption with key #' . $i . ' failed with exception: ' . $e->getMessage()); $lastException = $e; } } throw $lastException; } $nameId = $message->getNameId(); $sessionIndexes = $message->getSessionIndexes(); $numLoggedOut = sspmod_saml_SP_LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes); if ($numLoggedOut === FALSE) { /* This type of logout was unsupported. Use the old method. */ $source->handleLogout($idpEntityId); $numLoggedOut = count($sessionIndexes); } /* Create an send response. */ $lr = sspmod_saml_Message::buildLogoutResponse($spMetadata, $idpMetadata); $lr->setRelayState($message->getRelayState()); $lr->setInResponseTo($message->getId()); /* We should return a partial logout if we were unable to log out of all the given session(s). */ if ($numLoggedOut < count($sessionIndexes)) { $lr->setStatus(array('Code' => SAML2_Const::STATUS_SUCCESS, 'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT, 'Message' => 'Logged out of ' . $numLoggedOut . ' of ' . count($sessionIndexes) . ' sessions.')); } $binding->send($lr); } else { throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message)); }
/** * Send a logout response. * * @param SimpleSAML_IdP $idp The IdP we are sending a logout request from. * @param array &$state The logout state array. */ public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state) { assert('isset($state["saml:SPEntityId"])'); assert('isset($state["saml:RequestId"])'); assert('array_key_exists("saml:RelayState", $state)'); // Can be NULL. $spEntityId = $state['saml:SPEntityId']; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote'); $lr = sspmod_saml_Message::buildLogoutResponse($idpMetadata, $spMetadata); $lr->setInResponseTo($state['saml:RequestId']); $lr->setRelayState($state['saml:RelayState']); if (isset($state['core:Failed']) && $state['core:Failed']) { $partial = TRUE; $lr->setStatus(array('Code' => SAML2_Const::STATUS_SUCCESS, 'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT)); SimpleSAML_Logger::info('Sending logout response for partial logout to SP ' . var_export($spEntityId, TRUE)); } else { $partial = FALSE; SimpleSAML_Logger::debug('Sending logout response to SP ' . var_export($spEntityId, TRUE)); } SimpleSAML_Stats::log('saml:idp:LogoutResponse:sent', array('spEntityID' => $spEntityId, 'idpEntityID' => $idpMetadata->getString('entityid'), 'partial' => $partial)); $dst = $spMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST)); $binding = SAML2_Binding::getBinding($dst['Binding']); if (isset($dst['ResponseLocation'])) { $dst = $dst['ResponseLocation']; } else { $dst = $dst['Location']; } $lr->setDestination($dst); $binding->send($lr); }
/** * Send a logout response. * * @param array &$state The logout state array. */ public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state) { assert('isset($state["saml:SPEntityId"])'); assert('isset($state["saml:RequestId"])'); assert('array_key_exists("saml:RelayState", $state)'); // Can be NULL. $spEntityId = $state['saml:SPEntityId']; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote'); $lr = sspmod_saml_Message::buildLogoutResponse($idpMetadata, $spMetadata); $lr->setInResponseTo($state['saml:RequestId']); $lr->setRelayState($state['saml:RelayState']); if (isset($state['core:Failed']) && $state['core:Failed']) { $lr->setStatus(array('Code' => SAML2_Const::STATUS_SUCCESS, 'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT)); SimpleSAML_Logger::info('Sending logout response for partial logout to SP ' . var_export($spEntityId, TRUE)); } else { SimpleSAML_Logger::debug('Sending logout response to SP ' . var_export($spEntityId, TRUE)); } $binding = new SAML2_HTTPRedirect(); $binding->send($lr); }