From 46f22e706afa85f6eeb5af81503fd5f397e437e5 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Thu, 15 May 2008 16:13:36 +0000 Subject: [PATCH] SAML2-IdP: Fix IdP-initiated logout. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@574 44740490-163a-0410-bde0-09ae8108e29a --- www/saml2/idp/SingleLogoutService.php | 4 + www/saml2/idp/initSLO.php | 139 ++------------------------ 2 files changed, 12 insertions(+), 131 deletions(-) diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php index 18f27a917..e9a3f3f8c 100644 --- a/www/saml2/idp/SingleLogoutService.php +++ b/www/saml2/idp/SingleLogoutService.php @@ -205,6 +205,10 @@ if (isset($_GET['SAMLRequest'])) { /* Fetch the $logoutInfo variable. */ fetchLogoutInfo($_GET['LogoutID']); +} elseif(array_key_exists('ReturnTo', $_GET)) { + /* We have a ReturnTo - this is IdP initialized SLO. */ + $logoutInfo['RelayState'] = $_GET['ReturnTo']; + } else { /* * We have no idea what to do here. It is neither a logout request, a logout diff --git a/www/saml2/idp/initSLO.php b/www/saml2/idp/initSLO.php index 36869e9b3..f14185f00 100644 --- a/www/saml2/idp/initSLO.php +++ b/www/saml2/idp/initSLO.php @@ -5,149 +5,26 @@ require_once('../../../www/_include.php'); require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Utilities.php'); require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Session.php'); require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Logger.php'); -require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Metadata/MetaDataStorageHandler.php'); -require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutRequest.php'); -require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutResponse.php'); -require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Bindings/SAML20/HTTPRedirect.php'); -require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XHTML/Template.php'); $config = SimpleSAML_Configuration::getInstance(); -$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $session = SimpleSAML_Session::getInstance(); - SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout'); -if (!$config->getValue('enable.saml20-idp', false)) - SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS'); - -try { - $idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted'); -} catch (Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception); -} - - -/** - * If we get an incomming LogoutRequest then we initiate the logout process. - * in this case an SAML 2.0 SP is sending an request, which also is referred to as - * SP initiated Single Logout. - * - */ -if (isset($_GET['RelayState'])) { - - $relaystate = $_GET['RelayState']; - - /** - * No session exists. Just go to the RelayState. - */ - if($session === NULL) { - SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Did not find a session here, so we redirect to the RelayState'); - SimpleSAML_Utilities::redirect($relaystate); - exit; - } - - // Set local IdP session to invalid. - $session->doLogout(false); - - - /* - * Create an assoc array of the request to store in the session cache. - */ - $requestcache = array( - 'RelayState' => $relaystate - ); - - $session->setLogoutRequest($requestcache); - SimpleSAML_Logger::debug('SAML2.0 - IDP.initSSO: Setting cached request with relay state ' . $relaystate); - - //$session->set_sp_logout_completed($logoutrequest->getIssuer() ); - - -} - -$lookformore = true; -$spentityid = null; -do { - /* Dump the current sessions (for debugging). */ - $session->dump_sp_sessions(); - - /* - * We proceed to send logout requests to all remaining SPs. - */ - $spentityid = $session->get_next_sp_logout(); - - - // If there are no more SPs left, then we will not look for more SPs. - if (empty($spentityid)) $lookformore = false; - - try { - $spmetadata = $metadata->getMetadata($spentityid, 'saml20-sp-remote'); - } catch (Exception $e) { - continue; - } - - // If the SP we found have an SingleLogout endpoint then we will use it, and - // hence we do not need to look for more yet. - if (array_key_exists('SingleLogoutService', $spmetadata) && - !empty($spmetadata['SingleLogoutService']) ) $lookformore = false; - - if ($lookformore) - SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Will not logout from ' . $spentityid . ' looking for more SPs'); - -} while ($lookformore); - - - -/* - * We proceed to send logout requests to the first remaining SP. - */ -$spentityid = $session->get_next_sp_logout(); -if ($spentityid) { - - SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Logout next SP ' . $spentityid); - - try { - $lr = new SimpleSAML_XML_SAML20_LogoutRequest($config, $metadata); - - // ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) { - $req = $lr->generate($idpentityid, $spentityid, $session->getNameID(), $session->getSessionIndex(), 'IdP'); - - $httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata); - - $relayState = SimpleSAML_Utilities::selfURL(); - if (isset($_GET['RelayState'])) { - $relayState = $_GET['RelayState']; - } - - //$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP' - $httpredirect->sendMessage($req, $idpentityid, $spentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'IdP'); - - exit(); - - } catch(Exception $exception) { - - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTREQUEST', $exception); - - } - +if (!$config->getValue('enable.saml20-idp', false)) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS'); } -if ($config->getValue('debug', false)) - SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: LogoutService: All SPs done '); - -if (isset($_GET['RelayState'])) { - - $relayState = $_GET['RelayState']; - SimpleSAML_Utilities::redirect($relayState); - -} else { - +if (!isset($_GET['RelayState'])) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE'); - } +$returnTo = $_GET['RelayState']; +/* We turn processing over to the SingleLogoutService script. */ +SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/idp/SingleLogoutService.php', + array('ReturnTo' => $returnTo)); +?> \ No newline at end of file -- GitLab