function handleResponse() { try { $binding = SAML2_Binding::getCurrentBinding(); $response = $binding->receive(); } catch (Exception $e) { return; } SimpleSAML_Logger::debug('attributequery - received message.'); if (!$response instanceof SAML2_Response) { throw new SimpleSAML_Error_Exception('Unexpected message received to attribute query example.'); } $idpEntityId = $response->getIssuer(); if ($idpEntityId === NULL) { throw new SimpleSAML_Error_Exception('Missing issuer in response.'); } $idpMetadata = $GLOBALS['metadata']->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $spMetadata = $GLOBALS['metadata']->getMetaDataConfig($GLOBALS['spEntityId'], 'saml20-sp-hosted'); $assertion = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response); if (count($assertion) > 1) { throw new SimpleSAML_Error_Exception('More than one assertion in received response.'); } $assertion = $assertion[0]; $dataId = $response->getRelayState(); if ($dataId === NULL) { throw new SimpleSAML_Error_Exception('RelayState was lost during request.'); } $data = $GLOBALS['session']->getData('attributequeryexample:data', $dataId); $data['attributes'] = $assertion->getAttributes(); $GLOBALS['session']->setData('attributequeryexample:data', $dataId, $data, 3600); SimpleSAML_Utilities::redirect(SimpleSAML_Utilities::selfURLNoQuery(), array('dataId' => $dataId)); }
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); }
/** * @param SAML2_Response $response * @param SimpleSAML_Configuration $idpConfig */ private function addSigns(SAML2_Response $response, SimpleSAML_Configuration $idpConfig) { $assertions = $response->getAssertions(); $className = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer()->getMessageUtilClassName(); // Special case the 'normal' message verification class name so we have IDE support. if ($className === 'sspmod_saml_Message') { sspmod_saml_Message::addSign($idpConfig, SimpleSAML_Configuration::loadFromArray(array()), $assertions[0]); return; } $className::addSign($idpConfig, SimpleSAML_Configuration::loadFromArray(array()), $assertions[0]); }
/** * Receive a SAML 2 message sent using the HTTP-Artifact binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. */ public function receive() { if (array_key_exists('SAMLart', $_REQUEST)) { $artifact = base64_decode($_REQUEST['SAMLart']); $endpointIndex = bin2hex(substr($artifact, 2, 2)); $sourceId = bin2hex(substr($artifact, 4, 20)); } else { throw new Execption('Missing SAMLArt parameter.'); } $metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpmetadata = $metadataHandler->getMetaDataConfigForSha1($sourceId, 'saml20-idp-remote'); $endpoint = NULL; foreach ($idpmetadata->getEndpoints('ArtifactResolutionService') as $ep) { if ($ep['index'] === hexdec($endpointIndex)) { $endpoint = $ep; break; } } if ($endpoint === NULL) { throw new Exception('No ArtifactResolutionService with the correct index.'); } SimpleSAML_Logger::debug("ArtifactResolutionService endpoint being used is := " . $endpoint['Location']); //Construct the ArtifactResolve Request $ar = new SAML2_ArtifactResolve(); /* Set the request attributes */ $ar->setIssuer($this->spMetadata->getString('entityid')); $ar->setArtifact($_REQUEST['SAMLart']); $ar->setDestination($endpoint['Location']); /* Sign the request */ sspmod_saml_Message::addSign($this->spMetadata, $idpmetadata, $ar); // Shoaib - moved from the SOAPClient. $soap = new SAML2_SOAPClient(); // Send message through SoapClient $artifactResponse = $soap->send($ar, $this->spMetadata); if (!$artifactResponse->isSuccess()) { throw new Exception('Received error from ArtifactResolutionService.'); } $xml = $artifactResponse->getAny(); if ($xml === NULL) { /* Empty ArtifactResponse - possibly because of Artifact replay? */ return NULL; } $samlresponse = SAML2_Message::fromXML($xml); $samlresponse->addValidator(array(get_class($this), 'validateSignature'), $artifactResponse); if (isset($_REQUEST['RelayState'])) { $samlresponse->setRelayState($_REQUEST['RelayState']); } return $samlresponse; }
if ($state['saml:sp:AuthId'] !== $sourceId) { throw new SimpleSAML_Error_Exception('The authentication source id in the URL does not match the authentication source which sent the request.'); } /* Check that the issuer is the one we are expecting. */ assert('array_key_exists("ExpectedIssuer", $state)'); if ($state['ExpectedIssuer'] !== $idp) { throw new SimpleSAML_Error_Exception('The issuer of the response does not match to the identity provider we sent the request to.'); } } else { /* This is an unsolicited response. */ $state = array('saml:sp:isUnsolicited' => TRUE, 'saml:sp:AuthId' => $sourceId, 'saml:sp:RelayState' => $response->getRelayState()); } SimpleSAML_Logger::debug('Received SAML2 Response from ' . var_export($idp, TRUE) . '.'); $idpMetadata = $source->getIdPmetadata($idp); try { $assertions = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response); } catch (sspmod_saml_Error $e) { /* The status of the response wasn't "success". */ $e = $e->toException(); SimpleSAML_Auth_State::throwException($state, $e); } $authenticatingAuthority = NULL; $nameId = NULL; $sessionIndex = NULL; $expire = NULL; $attributes = array(); $foundAuthnStatement = FALSE; foreach ($assertions as $assertion) { /* Check for duplicate assertion (replay attack). */ $store = SimpleSAML_Store::getInstance(); if ($store !== FALSE) {
$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted'); if (!$idpMetadata->getBoolean('saml20.sendartifact', FALSE)) { throw new SimpleSAML_Error_Error('NOACCESS'); } $store = SimpleSAML_Store::getInstance(); if ($store === FALSE) { throw new Exception('Unable to send artifact without a datastore configured.'); } $binding = new SAML2_SOAP(); $request = $binding->receive(); if (!$request instanceof SAML2_ArtifactResolve) { throw new Exception('Message received on ArtifactResolutionService wasn\'t a ArtifactResolve request.'); } $issuer = $request->getIssuer(); $spMetadata = $metadata->getMetadataConfig($issuer, 'saml20-sp-remote'); $artifact = $request->getArtifact(); $responseData = $store->get('artifact', $artifact); $store->delete('artifact', $artifact); if ($responseData !== NULL) { $document = new DOMDocument(); $document->loadXML($responseData); $responseXML = $document->firstChild; } else { $responseXML = NULL; } $artifactResponse = new SAML2_ArtifactResponse(); $artifactResponse->setIssuer($idpEntityId); $artifactResponse->setInResponseTo($request->getId()); $artifactResponse->setAny($responseXML); sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $artifactResponse); $binding->send($artifactResponse);
/** * Start a SAML 2 logout operation. * * @param array $state The logout state. */ public function startSLO2(&$state) { assert('is_array($state)'); assert('array_key_exists("saml:logout:IdP", $state)'); assert('array_key_exists("saml:logout:NameID", $state)'); assert('array_key_exists("saml:logout:SessionIndex", $state)'); $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); $idp = $state['saml:logout:IdP']; $nameId = $state['saml:logout:NameID']; $sessionIndex = $state['saml:logout:SessionIndex']; $idpMetadata = $this->getIdPMetadata($idp); $endpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(\SAML2\Constants::BINDING_HTTP_REDIRECT, \SAML2\Constants::BINDING_HTTP_POST), FALSE); if ($endpoint === FALSE) { SimpleSAML\Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); return; } $lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $lr->setDestination($endpoint['Location']); $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata)); } $b = \SAML2\Binding::getBinding($endpoint['Binding']); $b->send($lr); assert('FALSE'); }
SimpleSAML_Utilities::redirectTrustedURL($extDiscoveryStorage, array('entityID' => $spentityid, 'return' => SimpleSAML_Utilities::addURLparameter($discourl, array('return' => SimpleSAML_Utilities::selfURL(), 'remember' => 'true', 'entityID' => $spentityid, 'returnIDParam' => 'idpentityid')), 'returnIDParam' => 'idpentityid', 'isPassive' => 'true')); } $discoparameters = array('entityID' => $spentityid, 'return' => SimpleSAML_Utilities::selfURL(), 'returnIDParam' => 'idpentityid'); $discoparameters['isPassive'] = $isPassive; if (sizeof($reachableIDPs) > 0) { $discoparameters['IDPList'] = $reachableIDPs; } SimpleSAML_Utilities::redirectTrustedURL($discourl, $discoparameters); } /* * Create and send authentication request to the IdP. */ try { $spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-hosted'); $idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-remote'); $ar = sspmod_saml_Message::buildAuthnRequest($spMetadata, $idpMetadata); $assertionConsumerServiceURL = $metadata->getGenerated('AssertionConsumerService', 'saml20-sp-hosted'); $ar->setAssertionConsumerServiceURL($assertionConsumerServiceURL); $ar->setRelayState($returnTo); if ($isPassive) { $ar->setIsPassive(TRUE); } if ($forceAuthn) { $ar->setForceAuthn(TRUE); } if (array_key_exists('IDPList', $spmetadata)) { $IDPList = array_unique(array_merge($IDPList, $spmetadata['IDPList'])); } if (isset($_GET['IDPList']) && !empty($_GET['IDPList'])) { $providers = $_GET['IDPList']; if (!is_array($providers)) {
throw $e; } * */ try { $binding = SAML2_Binding::getCurrentBinding(); $request = $binding->receive(); if (!$request instanceof SAML2_AuthnRequest) { throw new SimpleSAML_Error_BadRequest('Message received on authentication request endpoint wasn\'t an authentication request.'); } $spEntityId = $request->getIssuer(); if ($spEntityId === NULL) { throw new SimpleSAML_Error_BadRequest('Received message on authentication request endpoint without issuer.'); } $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote'); sspmod_saml_Message::validateMessage($spMetadata, $idpMetadata, $request); $supportedBindings = array(SAML2_Const::BINDING_PAOS); $consumerURL = $request->getAssertionConsumerServiceURL(); $protocolBinding = $request->getProtocolBinding(); $consumerIndex = $request->getAssertionConsumerServiceIndex(); $acsEndpoint = sspmod_saml_IdP_SAML2::getAssertionConsumerService($supportedBindings, $spMetadata, $consumerURL, $protocolBinding, $consumerIndex); $relayState = $request->getRelayState(); $requestId = $request->getId(); $state = array(); $state[sspmod_core_Auth_UserPassBase::AUTHID] = $auth; $state['LoginCompletedHandler'] = "ecp_finish_auth"; $state['SPMetadata'] = $spMetadata->toArray(); $state['saml:RequestId'] = $requestId; $state['saml:RelayState'] = $relayState; $state['saml:ConsumerURL'] = $acsEndpoint['Location']; $state['saml:Binding'] = $acsEndpoint['Binding'];
/** * build and send AttributeQuery */ function sendQuery($dataId, $url, $nameId, $attributes, $attributeNameFormat, $src, $dst) { assert('is_string($dataId)'); assert('is_string($url)'); assert('is_array($nameId)'); assert('is_array($attributes)'); SimpleSAML_Logger::debug('[attributeaggregator] - sending request'); $query = new SAML2_AttributeQuery(); $query->setRelayState($dataId); $query->setDestination($url); $query->setIssuer($src->getValue('entityid')); $query->setNameId($nameId); $query->setAttributeNameFormat($attributeNameFormat); if (!empty($attributes)) { $query->setAttributes($attributes); } sspmod_saml_Message::addSign($src, $dst, $query); if (!$query->getSignatureKey()) { throw new SimpleSAML_Error_Exception('[attributeaggregator] - Unable to find private key for signing attribute request.'); } SimpleSAML_Logger::debug('[attributeaggregator] - sending attribute query: ' . var_export($query, 1)); $binding = new SAML2_SOAPClient(); $result = $binding->send($query, $src); return $result; }
} /* Filter which attribute values we should return. */ $returnAttributes[$name] = array_intersect($values, $attributes[$name]); } } /* $returnAttributes contains the attributes we should return. Send them. */ $assertion = new SAML2_Assertion(); $assertion->setIssuer($idpEntityId); $assertion->setNameId($query->getNameId()); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + 5 * 60); $assertion->setValidAudiences(array($spEntityId)); $assertion->setAttributes($returnAttributes); $assertion->setAttributeNameFormat($attributeNameFormat); $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->Method = SAML2_Const::CM_BEARER; $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + 5 * 60; $sc->SubjectConfirmationData->Recipient = $endpoint; $sc->SubjectConfirmationData->InResponseTo = $query->getId(); $assertion->setSubjectConfirmation(array($sc)); sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $assertion); $response = new SAML2_Response(); $response->setRelayState($query->getRelayState()); $response->setDestination($endpoint); $response->setIssuer($idpEntityId); $response->setInResponseTo($query->getId()); $response->setAssertions(array($assertion)); sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $response); $binding = new SAML2_HTTPPost(); $binding->send($response);
/** * Start a SAML 2 logout operation. * * @param array $state The logout state. */ public function startSLO2(&$state) { assert('is_array($state)'); assert('array_key_exists("saml:logout:IdP", $state)'); assert('array_key_exists("saml:logout:NameID", $state)'); assert('array_key_exists("saml:logout:SessionIndex", $state)'); $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); $idp = $state['saml:logout:IdP']; $nameId = $state['saml:logout:NameID']; $sessionIndex = $state['saml:logout:SessionIndex']; $idpMetadata = $this->getIdPMetadata($idp); $endpoint = $idpMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), FALSE); if ($endpoint === FALSE) { SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); return; } $lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $b = new SAML2_HTTPRedirect(); $b->send($lr); assert('FALSE'); }
private function buildResponse($returnAttributes) { /* SubjectConfirmation */ $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->Method = SAML2_Const::CM_BEARER; $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotBefore = time(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + $this->config->getInteger('validFor'); $sc->SubjectConfirmationData->InResponseTo = $this->query->getId(); $assertion = new SAML2_Assertion(); $assertion->setSubjectConfirmation(array($sc)); $assertion->setIssuer($this->aaEntityId); $assertion->setNameId($this->query->getNameId()); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + $this->config->getInteger('validFor')); $assertion->setValidAudiences(array($this->spEntityId)); $assertion->setAttributes($returnAttributes); $assertion->setAttributeNameFormat($this->attributeNameFormat); if ($this->signAssertion) { sspmod_saml_Message::addSign($this->aaMetadata, $this->spMetadata, $assertion); } /* The Response */ $response = new SAML2_Response(); $response->setRelayState($this->query->getRelayState()); $response->setIssuer($this->aaEntityId); $response->setInResponseTo($this->query->getId()); $response->setAssertions(array($assertion)); if ($this->signResponse) { sspmod_saml_Message::addSign($this->aaMetadata, $this->spMetadata, $response); } return $response; }
} $associations = $idp->getAssociations(); if (!isset($associations[$assocId])) { throw new SimpleSAML_Error_BadRequest('Invalid association id.'); } $association = $associations[$assocId]; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote'); $lr = sspmod_saml_Message::buildLogoutRequest($idpMetadata, $spMetadata); $lr->setSessionIndex($association['saml:SessionIndex']); $lr->setNameId($association['saml:NameID']); $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); } $lr->setNotOnOrAfter(time() + $assertionLifetime); $encryptNameId = $spMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata)); } SimpleSAML_Stats::log('saml:idp:LogoutRequest:sent', array('spEntityID' => $association['saml:entityID'], 'idpEntityID' => $idpMetadata->getString('entityid'))); $bindings = array(\SAML2\Constants::BINDING_HTTP_POST); $dst = $spMetadata->getDefaultEndpoint('SingleLogoutService', $bindings); $binding = \SAML2\Binding::getBinding($dst['Binding']); $lr->setDestination($dst['Location']); $lr->setRelayState($relayState); $binding->send($lr);
/** * Build a authentication response based on information in the metadata. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param string $consumerURL The Destination URL of the response. */ private static function buildResponse(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, $consumerURL) { $signResponse = $spMetadata->getBoolean('saml20.sign.response', NULL); if ($signResponse === NULL) { $signResponse = $idpMetadata->getBoolean('saml20.sign.response', TRUE); } $r = new SAML2_Response(); $r->setIssuer($idpMetadata->getString('entityid')); $r->setDestination($consumerURL); if ($signResponse) { sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $r); } return $r; }
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)); }
} try { $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpEntityId = $session->getAuthData('saml2', 'saml:sp:IdP'); if ($idpEntityId === NULL) { SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: User not authenticated with an IdP.'); SimpleSAML_Utilities::redirectTrustedURL($returnTo); } $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $SLOendpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST), NULL); if ($SLOendpoint === NULL) { $session->doLogout('saml2'); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: No SingleLogoutService endpoint supported in the IdP.'); SimpleSAML_Utilities::redirectTrustedURL($returnTo); } $spEntityId = isset($_GET['spentityid']) ? $_GET['spentityid'] : $metadata->getMetaDataCurrentEntityID(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-hosted'); $nameId = $session->getAuthData('saml2', 'saml:sp:NameID'); $lr = sspmod_saml_Message::buildLogoutRequest($spMetadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($session->getAuthData('saml2', 'saml:sp:SessionIndex')); $lr->setDestination($SLOendpoint['Location']); $session->doLogout('saml2'); /* Save the $returnTo URL until the user returns from the IdP. */ $session->setData('spLogoutReturnTo', $lr->getId(), $returnTo); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: SP (' . $spEntityId . ') is sending logout request to IdP (' . $idpEntityId . ')'); $b = SAML2_Binding::getBinding($SLOendpoint['Binding']); $b->send($lr); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CREATEREQUEST', $exception); }