21 require_once SQ_INCLUDE_PATH.
'/asset.inc';
48 parent::__construct($assetid);
64 return $this->
attr(
'name');
82 if (!parent::_createAdditional($link))
return FALSE;
86 if (empty($link))
return TRUE;
103 $saml_account_manager_data = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'saml_account_manager', TRUE,
'saml2_single_logout_service',
'minor');
104 $saml_account_manager = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($saml_account_manager_data[
'majorid']);
106 if(!$saml_account_manager->isSimplesamlphpInstalled()) {
107 echo(
'simplesamlphp library is not installed');
111 require_once SQ_TOOL_SIMPLESAMLPHP_PATH.
'/lib/_autoload.php';
112 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_auth_manager.inc';
113 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_sp.inc';
115 $sourceId = $saml_account_manager->attr(
'auth_source');
117 $config = SimpleSAML_Configuration::getConfig(
'authsources.php');
118 $authConfig = $config->getArray($sourceId, NULL);
122 $binding = SAML2_Binding::getCurrentBinding();
124 catch (Exception $e) {
125 echo($e->getMessage());
129 $binding = SAML2_Binding::getCurrentBinding();
130 $message = $binding->receive();
132 $idpEntityId = $message->getIssuer();
133 if ($idpEntityId === NULL) {
135 throw new SimpleSAML_Error_BadRequest(
'Received message on logout endpoint without issuer.');
138 $spEntityId = $source->getEntityId();
140 $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
141 $idpMetadata = $source->getIdPMetadata($idpEntityId);
142 $spMetadata = $source->getMetadata();
144 sspmod_saml_Message::validateMessage($idpMetadata, $spMetadata, $message);
146 $destination = $message->getDestination();
147 if ($destination !== NULL && $destination !== SimpleSAML_Utilities::selfURLNoQuery()) {
148 throw new SimpleSAML_Error_Exception(
'Destination in logout message is wrong.');
151 if ($message instanceof SAML2_LogoutResponse) {
153 $relayState = $message->getRelayState();
154 if ($relayState === NULL) {
156 throw new SimpleSAML_Error_BadRequest(
'Missing RelayState in logout response.');
159 if (!$message->isSuccess()) {
160 SimpleSAML_Logger::warning(
'Unsuccessful logout. Status was: ' . sspmod_saml_Message::getResponseError($message));
163 $state = SimpleSAML_Auth_State::loadState($relayState,
'saml:slosent');
164 $state[
'saml:sp:LogoutStatus'] = $message->getStatus();
165 SimpleSAML_Auth_Source::completeLogout($state);
167 } elseif ($message instanceof SAML2_LogoutRequest) {
169 SimpleSAML_Logger::debug(
'SAML2 Single Logout Service: Request from ' . $idpEntityId);
170 SimpleSAML_Logger::stats(
'saml20-idp-SLO idpinit ' . $spEntityId .
' ' . $idpEntityId);
172 if ($message->isNameIdEncrypted()) {
174 $keys = sspmod_saml_Message::getDecryptionKeys($idpMetadata, $spMetadata);
175 }
catch (Exception $e) {
176 throw new SimpleSAML_Error_Exception(
'Error decrypting NameID: ' . $e->getMessage());
179 $lastException = NULL;
180 foreach ($keys as $i => $key) {
182 $message->decryptNameId($key);
183 SimpleSAML_Logger::debug(
'Decryption with key #' . $i .
' succeeded.');
184 $lastException = NULL;
186 }
catch (Exception $e) {
187 SimpleSAML_Logger::debug(
'Decryption with key #' . $i .
' failed with exception: ' . $e->getMessage());
191 if ($lastException !== NULL) {
192 throw $lastException;
196 $nameId = $message->getNameId();
197 $sessionIndexes = $message->getSessionIndexes();
199 $numLoggedOut = sspmod_saml_SP_LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes);
200 if ($numLoggedOut === FALSE) {
202 $source->handleLogout($idpEntityId);
203 $numLoggedOut = count($sessionIndexes);
207 $lr = sspmod_saml_Message::buildLogoutResponse($spMetadata, $idpMetadata);
208 $lr->setRelayState($message->getRelayState());
209 $lr->setInResponseTo($message->getId());
211 if ($numLoggedOut < count($sessionIndexes)) {
212 SimpleSAML_Logger::warning(
'Logged out of ' . $numLoggedOut .
' of ' . count($sessionIndexes) .
' sessions.');
217 throw new SimpleSAML_Error_BadRequest(
'Unknown message received on logout endpoint: ' . get_class($message));