Skip to content
Snippets Groups Projects
Commit 2dd415e1 authored by Andreas Åkre Solberg's avatar Andreas Åkre Solberg
Browse files

add support for idp-initiated SLO with iframe.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1348 44740490-163a-0410-bde0-09ae8108e29a
parent a49e6f51
No related branches found
No related tags found
No related merge requests found
...@@ -57,6 +57,7 @@ function startslo() { ...@@ -57,6 +57,7 @@ function startslo() {
function slocompletesp($entityhash) { function slocompletesp($entityhash) {
$("table#slostatustable tr#" + $entityhash).filter(".inprogress").removeClass("inprogress").addClass("completed"). $("table#slostatustable tr#" + $entityhash).filter(".inprogress").removeClass("inprogress").addClass("completed").
children().fadeOut("fast").fadeIn("fast"); children().fadeOut("fast").fadeIn("fast");
alert("complete SP " + $entityhash );
} }
...@@ -97,9 +98,10 @@ function sendResponse() { ...@@ -97,9 +98,10 @@ function sendResponse() {
<?php <?php
$requestername = is_array($this->data['requesterName']) ? if (array_key_exists('requestername', $this->data)) {
$this->getTranslation($this->data['requesterName']) : $this->data['requesterName']; $requestername = is_array($this->data['requesterName']) ?
$this->getTranslation($this->data['requesterName']) : $this->data['requesterName'];
}
#echo('<p>' . $this->t('{logout:description}', array('%REQUESTERNAME%' => $requestername)) . '</p>'); #echo('<p>' . $this->t('{logout:description}', array('%REQUESTERNAME%' => $requestername)) . '</p>');
?> ?>
...@@ -108,11 +110,12 @@ function sendResponse() { ...@@ -108,11 +110,12 @@ function sendResponse() {
<?php <?php
echo('<div><img style="float: left; margin-right: 12px" src="/' . $this->data['baseurlpath'] . 'resources/icons/checkmark48.png" alt="Successful logout" />'); if (array_key_exists('requestername', $this->data)) {
echo('<p style="padding-top: 16px; ">' . $this->t('{logout:loggedoutfrom}', array('%SP%' => '<strong>' .$requestername.'</strong>')) . '</p>'); echo('<div><img style="float: left; margin-right: 12px" src="/' . $this->data['baseurlpath'] . 'resources/icons/checkmark48.png" alt="Successful logout" />');
echo('<p style="height: 0px; clear: left;"></p>'); echo('<p style="padding-top: 16px; ">' . $this->t('{logout:loggedoutfrom}', array('%SP%' => '<strong>' .$requestername.'</strong>')) . '</p>');
echo('</div>'); echo('<p style="height: 0px; clear: left;"></p>');
echo('</div>');
}
echo('<div style="margin-top: 3em; clear: both">'); echo('<div style="margin-top: 3em; clear: both">');
echo('<p style="margin-bottom: .5em">' . $this->t('{logout:also_from}') . '</p>'); echo('<p style="margin-bottom: .5em">' . $this->t('{logout:also_from}') . '</p>');
...@@ -187,7 +190,16 @@ function sendResponse() { ...@@ -187,7 +190,16 @@ function sendResponse() {
<?php echo $this->t('{logout:logout_all_question}'); ?> <br /> <?php echo $this->t('{logout:logout_all_question}'); ?> <br />
</p> </p>
<input type="button" id="ok" name="ok" value="<?php echo $this->t('{logout:logout_all}'); ?>" /> <input type="button" id="ok" name="ok" value="<?php echo $this->t('{logout:logout_all}'); ?>" />
<input type="button" id="cancel" name="cancel" value="<?php echo $this->t('{logout:logout_only}', array('%SP%' => $requestername)); ?>" /> <?php
if (array_key_exists('requestername', $this->data)) {
echo '<input type="button" id="cancel" name="cancel" value="' . $this->t('{logout:logout_only}', array('%SP%' => $requestername)) . '" />';
} else {
echo '<input type="button" id="cancel" name="cancel" value="' . $this->t('{logout:no}') . '" />';
}
?>
<p id="incapablesps" > <p id="incapablesps" >
......
...@@ -115,7 +115,7 @@ if (isset($_GET['SAMLRequest'])) { ...@@ -115,7 +115,7 @@ if (isset($_GET['SAMLRequest'])) {
$responder = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted'); $responder = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: got Logoutrequest from ' . $logoutrequest->getIssuer()); SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: got Logoutrequest from ' . $requester);
SimpleSAML_Logger::stats('saml20-idp-SLO spinit ' . $requester . ' ' . $responder); SimpleSAML_Logger::stats('saml20-idp-SLO spinit ' . $requester . ' ' . $responder);
/* Check if we have a valid session. */ /* Check if we have a valid session. */
......
...@@ -17,6 +17,8 @@ $session = SimpleSAML_Session::getInstance(); ...@@ -17,6 +17,8 @@ $session = SimpleSAML_Session::getInstance();
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)'); SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)');
SimpleSAML_Logger::debug('Initially; ' . join(',', $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE)));
if (!$config->getValue('enable.saml20-idp', false)) if (!$config->getValue('enable.saml20-idp', false))
SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS'); SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
...@@ -103,8 +105,8 @@ function updateslostatus() { ...@@ -103,8 +105,8 @@ function updateslostatus() {
foreach ($templistofsps AS $spentityid) { foreach ($templistofsps AS $spentityid) {
if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid; if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid;
} }
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: templistofsps ' . var_export($templistofsps, TRUE)); SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: templistofsps ' . join(',', $templistofsps));
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: listofsps ' . var_export($listofsps, TRUE)); SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: listofsps ' . join(',', $listofsps));
// Using template object to be able to translate name of service provider. // Using template object to be able to translate name of service provider.
......
...@@ -70,7 +70,6 @@ if (isset($_GET['SAMLResponse'])) { ...@@ -70,7 +70,6 @@ if (isset($_GET['SAMLResponse'])) {
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS', SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS',
new Exception('No valid SAMLResponse found? Probably some error in remote partys metadata that sends something to this endpoint that is not SAML LogoutResponses') ); new Exception('No valid SAMLResponse found? Probably some error in remote partys metadata that sends something to this endpoint that is not SAML LogoutResponses') );
# echo 'Not set: SAMLResponse';
} }
?> ?>
\ No newline at end of file
<?php
/**
* IdP Initiated Single Log-Out. Requires one parameter: RelayState.
*
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package simpleSAMLphp
* @version $Id$
*/
require_once('../../_include.php');
$config = SimpleSAML_Configuration::getInstance();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$session = SimpleSAML_Session::getInstance();
SimpleSAML_Logger::info('SAML2.0 - IdP.idpInitSingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)');
SimpleSAML_Logger::debug('Initially; ' . join(',', $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE)));
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);
}
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Got IdP entity id: ' . $idpentityid);
$logouttype = 'traditional';
$idpmeta = $metadata->getMetaDataCurrent('saml20-idp-hosted');
if (array_key_exists('logouttype', $idpmeta)) $logouttype = $idpmeta['logouttype'];
if ($logouttype !== 'iframe')
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
/**
* This function retrieves the logout info with the given ID.
*
* @param $id The identifier of the logout info.
*/
function fetchLogoutInfo($id) {
global $session;
global $logoutInfo;
$logoutInfo = $session->getData('idplogoutresponsedata', $id);
if($logoutInfo === NULL) {
SimpleSAML_Logger::warning('SAML2.0 - IdP.SingleLogoutService: Lost logout information.');
}
}
/**
* This function saves the logout info with the given ID.
*
* @param $id The identifier the logout info should be saved with.
*/
function saveLogoutInfo($id) {
global $session;
global $logoutInfo;
$session->setData('idplogoutresponsedata', $id, $logoutInfo);
}
// Include XAJAX definition.
require_once(SimpleSAML_Utilities::resolvePath('libextinc') . '/xajax/xajax.inc.php');
/*
* This function is called via AJAX and will send LogoutRequest to one single SP by
* sending a LogoutRequest using HTTP-REDIRECT
*/
function updateslostatus() {
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version) within updateslostatus() ');
$config = SimpleSAML_Configuration::getInstance();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$session = SimpleSAML_Session::getInstance();
$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
$listofsps = array();
foreach ($templistofsps AS $spentityid) {
if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid;
}
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: templistofsps ' . join(',', $templistofsps));
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: listofsps ' . join(',', $listofsps));
// Using template object to be able to translate name of service provider.
$t = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
// Instantiate the xajaxResponse object
$objResponse = new xajaxResponse();
foreach ($listofsps AS $spentityid) {
SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Completed ' . $spentityid);
// add a command to the response to assign the innerHTML attribute of
// the element with id="SomeElementId" to whatever the new content is
$spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote');
$name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid;
$spname = is_array($name) ? $t->getTranslation($name) : $name;
$objResponse->addScriptCall('slocompletesp', 'e' . sha1($spentityid));
}
if (count($templistofsps) === count($listofsps)) {
$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
foreach ($templistofsps AS $spentityid) {
$session->set_sp_logout_completed($spentityid);
setcookie('spstate-' . sha1($spentityid) , '', time() - 3600); // Delete cookie
}
$objResponse->addScriptCall('slocompleted');
/**
* Clean up session object to save storage.
*/
if ($config->getValue('debug', false))
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size before cleaning: ' . $session->getSize());
$session->clean();
if ($config->getValue('debug', false))
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size after cleaning: ' . $session->getSize());
} else {
SimpleSAML_Logger::debug('SAML2.0 - sp_logout_completed FALSE');
}
//return the xajaxResponse object
return $objResponse;
}
$xajax = new xajax();
$xajax->registerFunction("updateslostatus");
$xajax->processRequests();
/**
* Which URL to send the user to after logout?
*/
$relayState = NULL;
if (array_key_exists('RelayState', $_REQUEST)) $relayState = $_REQUEST['RelayState'];
// Do logout from the IdP
$session->doLogout();
// Debug entries in the log about what services the user is logged into.
$session->dump_sp_sessions();
/*
* Generate a list of all service providers, and create a LogoutRequest message for all these SPs.
*/
$listofsps = $session->get_sp_list();
$sparray = array();
$sparrayNoLogout = array();
foreach ($listofsps AS $spentityid) {
// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
$nameId = $session->getSessionNameId('saml20-sp-remote', $spentityid);
if($nameId === NULL) {
$nameId = $session->getNameID();
}
$spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote');
$name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid;
try {
$lr = new SimpleSAML_XML_SAML20_LogoutRequest($config, $metadata);
$req = $lr->generate($idpentityid, $spentityid, $nameId, $session->getSessionIndex(), 'IdP');
$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
// $request, $localentityid, $remoteentityid, $relayState = null, $endpoint = 'SingleSignOnService', $direction = 'SAMLRequest', $mode = 'SP'
$url = $httpredirect->getRedirectURL($req, $idpentityid, $spentityid, NULL, 'SingleLogoutService', 'SAMLRequest', 'IdP');
$sparray[$spentityid] = array('url' => $url, 'name' => $name);
} catch (Exception $e) {
$sparrayNoLogout[$spentityid] = array('name' => $name);
}
}
SimpleSAML_Logger::debug('SAML2.0 - SP Counter. other SPs with SLO support (' . count($sparray) . ') without SLO support (' . count($sparrayNoLogout) . ')');
#print_r($sparray);
/*
* If the user is not logged into any other SPs.
*/
if (count($sparray) === 0) {
SimpleSAML_Utilities::redirect($relayState);
exit;
}
$et = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
$et->data['header'] = 'Logout';
$et->data['sparray'] = $sparray;
$et->data['sparrayNoLogout'] = $sparrayNoLogout;
$et->data['logoutresponse'] = $relayState;
$et->data['xajax'] = $xajax;
#$et->data['idpInitRelayState'] = $relayState;
# $et->data['requesterName'] = $spname;
$et->data['head'] = $xajax->getJavascript();
$et->show();
exit(0);
?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment