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

Adding improvements to iframe based SLO. Now user is asked before SLO starts.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1066 44740490-163a-0410-bde0-09ae8108e29a
parent c78e9dd9
No related branches found
No related tags found
No related merge requests found
<?php <?php
$iframehtml = '';
foreach ($this->data['sparray'] AS $sp) {
$iframehtml .= '<iframe class="hiddeniframe" onload="xajax_updateslostatus()" style="border: 1px solid #888; width: 80%; height: 100px" src="' . htmlentities($sp['url']) . '" ></iframe>';
}
# $iframehtml = str_replace('"', '\"', $iframehtml);
# $iframehtml = str_replace("\n", '', $iframehtml);
# $iframehtml = str_replace("\r", '', $iframehtml);
$this->data['hideLanguageBar'] = TRUE;
$this->data['head'] .= '<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery.js"></script>';
$this->data['head'] .= '<link rel="stylesheet" type="text/css" href="/' . $this->data['baseurlpath'] . 'resources/slo.css" />';
$nologoutSPs = (count($this->data['sparrayNoLogout']) > 0);
$this->data['head'] .= ' $this->data['head'] .= '
<script type="text/javascript" language="JavaScript"> <script type="text/javascript" language="JavaScript">
function showdiv(id) {
//safe function to show an element with a specified id
$(document).ready(function() {
if (document.getElementById) { // DOM3 = IE5, NS6 $("div#requirejavascript").show();
document.getElementById(id).style.display = \'block\'; /* $("div.completedButWarnings").hide(); */
} $("div#interrupt").hide();
else { $("input#ok").click(function () {
if (document.layers) { // Netscape 4 startslo();
document.id.display = \'block\'; });
} $("input#cancel").click(function () {
else { // IE 4 sendResponse();
document.all.id.style.display = \'block\'; });
} $("input#returnanyway").click(function () {
} sendResponse();
});
$("input#interruptbutton").click(function () {
sendResponse();
});
' . ($nologoutSPs ? '$("div#incapablesps").show();' : '$("div#incapablesps").hide();') . '
});
function toolong() {
$("div#interrupt").show().fadeOut("fast").fadeIn("fast");
}
/* This function is called when users clicks to start single logout */
function startslo() {
$("#confirmation").hide();
$("#hiddeniframecontainer").html("' . str_replace('"', '\"', $iframehtml) . '");
$("table#slostatustable tr.onhold").removeClass("onhold").addClass("inprogress");
$("div.completedButWarnings").show();
setTimeout("toolong()", 16000);
}
/* This function is called from the AJAX response with xajax with the hash of the entityid of the SP */
function slocompletesp($entityhash) {
$("table#slostatustable tr#" + $entityhash).filter(".inprogress").removeClass("inprogress").addClass("completed").
children().fadeOut("fast").fadeIn("fast");
}
/* SLO completed for all sps. */
function slocompleted() {
/* $("div.completedButWarnings").show(); */
' . ($nologoutSPs ? ' ' : 'setTimeout("sendResponse()", 2000);') . '
}
function sendResponse() {
window.location = "' . $this->data['logoutresponse'] . '";
} }
</script>'; </script>';
...@@ -26,59 +76,139 @@ function showdiv(id) { ...@@ -26,59 +76,139 @@ function showdiv(id) {
?> ?>
<!-- Proper fallback for browsers that do not support javascript or have javascript turned off -->
<noscript>
<div id="nojavascriptframe">
<iframe style="margin: 1em; width: 90%; height: 5em; border: 1px solid #eee" src="SingleLogoutServiceiFrameNoJavascript.php?response=<?php echo urlencode($this->data['logoutresponse']); ?>"></iframe>
</div>
<?php
foreach ($this->data['sparray'] AS $sp) {
echo '<iframe class="hiddeniframe" onload="xajax_updateslostatus()" style="border: 1px solid #888; width: 80%; height: 100px"
src="' . htmlentities($sp['url']) . '" ></iframe>' . "\n";
}
?>
</noscript>
<div id="requirejavascript" style="display: none">
<?php
$requestername = is_array($this->data['requesterName']) ?
$this->getTranslation($this->data['requesterName']) : $this->data['requesterName'];
?>
<p>You have initiated a <strong>global logout</strong> from the service <strong><?php echo $requestername; ?></strong>. Global logout means you will be logged out from all of the services listed below.</p>
<!-- <div class="loggedout">Logout was started from <?php echo $requestername; ?>.</div> -->
<?php
<noscript> echo '<table id="slostatustable">';
<div id="nojavascriptframe">
<iframe style="margin: 1em; width: 90%; height: 5em; border: 1px solid #eee" src="SingleLogoutServiceiFrameNoJavascript.php?response=<?php echo urlencode($this->data['logoutresponse']); ?>"></iframe>
</div>
</noscript>
<div id="requirejavascript" style="display: none">
<noscript><div style="background: #500; color: white; border: 1px solod #300">Ignore the logout indicators below. They will not be updated as your browser do not support javascript. Logout will still work.</div></noscript> echo '<tr class="initiated" id="e' . sha1($spentityid) . '">' . "\n";
echo ' <td><img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] .
'resources/icons/silk/accept.png" alt="Initiated from" /></td>' . "\n";
echo ' <td>Initiated logout</td>';
echo ' <td>' . $requestername . '</td>' ."\n";
echo '</tr>' . "\n";
<?php
foreach ($this->data['sparrayNoLogout'] AS $spentityid => $sp) {
$spname = is_array($sp['name']) ? $this->getTranslation($sp['name']) : $sp['name'];
echo '<tr class="initiated" id="e' . sha1($spentityid) . '">' . "\n";
echo ' <td><img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] .
'resources/icons/silk/delete.png" alt="Initiated from" /></td>' . "\n";
echo ' <td>Logout not supported</td>';
echo ' <td>' . $spname . '</td>' ."\n";
echo '</tr>' . "\n";
}
foreach ($this->data['sparray'] AS $spentityid => $sp) {
$spname = is_array($sp['name']) ? $this->getTranslation($sp['name']) : $sp['name'];
$requestername = is_array($this->data['requesterName']) ? echo '<tr class="ready onhold" id="e' . sha1($spentityid) . '">' . "\n";
$this->getTranslation($this->data['requesterName']) : $this->data['requesterName'];
echo ' <td class="icons">';
echo ' <img class="completed" src="/' . $this->data['baseurlpath'] . 'resources/icons/silk/accept.png" alt="Completed" />' . "\n";
echo ' <img class="onhold" src="/' . $this->data['baseurlpath'] . 'resources/icons/silk/control_pause.png" alt="SP SLO on hold" />' . "\n";
echo ' <img class="inprogress" src="/' . $this->data['baseurlpath'] . 'resources/progress.gif" alt="Progress bar" />' . "\n";
echo ' <img class="failed" src="/' . $this->data['baseurlpath'] . 'resources/icons/silk/exclamation.png" alt="Failed" />' . "\n";
echo ' </td>' . "\n";
?> echo ' <td class="statustext">';
<p>You have initiated a <strong>global logout</strong> from the service <strong><?php echo $requestername; ?></strong>. Global logout means you will be logged out from all services connected to this identity provider. This page will show the status of the logout proccess for all of the services you are logged into.</p> echo ' <span class="completed">Completed</span>' . "\n";
echo ' <span class="onhold">On hold</span>' . "\n";
<div class="loggedout">Logout was started from <?php echo $requestername; ?>.</div> echo ' <span class="inprogress">Logging out…</span>' . "\n";
echo ' <span class="failed">Logout failed</span>' . "\n";
echo ' </td>';
echo ' <td>' . $spname . '</td>' ."\n";
echo '</tr>' . "\n";
// echo '<div class="inprogress" id="e' . sha1($spentityid) . '">
// <img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] . 'resources/progress.gif" alt="Progress bar" />Wait... is logging out from <strong>' . $spname . '</strong></div>' . "\n";
}
echo '</table>';
$completed = ' class="allcompleted"';
if (count($this->data['sparray']) > 0) {
$completed = '';
}
<?php
?>
foreach ($this->data['sparray'] AS $sp) {
echo '<iframe class="hiddeniframe" onload="xajax_updateslostatus()" style="border: 1px solid #888; width: 80%; height: 100px" src="' . $sp['url'] . '" ></iframe>' . "\n"; <p id="confirmation" style="margin-top: 1em" >Do you want to continue global logout? <br />
} <input type="button" id="ok" name="ok" value="Yes, continue logout" />
<input type="button" id="cancel" name="cancel" value="Cancel logout" />
foreach ($this->data['sparray'] AS $spentityid => $sp) { </p>
$spname = is_array($sp['name']) ? $this->getTranslation($sp['name']) : $sp['name'];
echo '<div class="inprogress" id="e' . sha1($spentityid) . '">
<img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] . 'resources/progress.gif" alt="Progress bar" />Wait... is logging out from <strong>' . $spname . '</strong></div>' . "\n";
}
$completed = ' class="allcompleted"'; <div id="interrupt" style="margin-top: 1em; border: 1px solid #ccc; padding: 1em; background: #eaeaea" >
if (count($this->data['sparray']) > 0) { <p style="margin: 0px; padding; 0px">
$completed = ''; <img src="/<?php echo($this->data['baseurlpath']); ?>resources/icons/timeout.png"
} style="float: left; margin: 0px 5px 0px 0px"
/>
If some of the service providers do not respond in reasonable time, you are encouraged to close your browser to ensure sessions are closed. <br />
<input type="button" id="interruptbutton" name="interrupt" value="Return to service" />
</p>
</div>
?> <div id="incapablesps" style="margin-top: 1em; border: 1px solid #ccc; padding: 1em; background: #eaeaea" >
<p style="margin: 0px; padding; 0px">
<div id="interrupt"<?php echo $completed; ?>>[ <a href="<?php echo $this->data['logoutresponse']; ?>">Interrupt logging out and go back to service</a> ]</div> <img src="/<?php echo($this->data['baseurlpath']); ?>resources/icons/caution.png"
<div id="iscompleted"<?php echo $completed; ?>>You have successfully logged out from all services listed above. style="float: left; margin: 0px 5px 0px 0px"
<!-- form method="get" action="<?php echo $this->data['logoutresponse']; ?>"> />
<input type="submit" name="s" value="OK, continue back to <?php echo $this->data['requesterName']; ?> to complete the logout process." /> One or more of the services you are logged into <i>do not support logout</i>. To ensure that all your sessions are closed, you are encouraged to <i>close your webbrowser</i>.
</form --> </p>
<br />[ <a href="<?php echo $this->data['logoutresponse']; ?>">OK, continue back to <?php echo $requestername; ?> to complete the logout process.</a> ]
</div>
<div class="completedButWarnings">
<input type="button" id="returnanyway" name="ok" value="Return to service" />
</div> </div>
<script type="text/javascript" language="JavaScript"> </div>
showdiv('requirejavascript');
</script> <div id="hiddeniframecontainer" stye="margin: 0px; padding: 0px;"></div>
</div>
<!--
<script type="text/javascript" language="JavaScript">
showdiv('requirejavascript');
</script>
-->
<?php $this->includeAtTemplateBase('includes/footer.php'); ?> <?php $this->includeAtTemplateBase('includes/footer.php'); ?>
\ No newline at end of file
...@@ -267,50 +267,3 @@ div.preferredidp { ...@@ -267,50 +267,3 @@ div.preferredidp {
div.allcompleted#interrupt {
display: none;
}
div#interrupt a:link {
color: #036;
border-bottom: 1px dotted #036;
text-decoration: none;
}
div#interrupt a:hover {
border-bottom: 1px solid #036;
}
div#interrupt {
display: block;
border: 3px solid #036;
background: #39F;
padding: 1em;
margin: .2em;
}
div#iscompleted {
display: none;
border: 3px solid #993;
background: #FF9;
padding: 1em;
margin: .2em;
}
div.allcompleted#iscompleted {
display: block ! important;
}
div.inprogress, div.loggedout {
background: #eee;
color: #444;
padding: .2em 1em;
margin: .2em;
}
div.inprogress {
border: 1px dotted #888;
}
div.loggedout {
border: 1px solid #888;
background: #9f9 ! important ;
}
iframe.hiddeniframe {
display: none;
}
www/resources/icons/silk/accept.png

781 B

www/resources/icons/silk/cancel.png

587 B

www/resources/icons/silk/control_pause.png

598 B

www/resources/icons/silk/delete.png

715 B

www/resources/icons/silk/exclamation.png

701 B

www/resources/icons/silk/tick.png

537 B

www/resources/icons/timeout.png

3.91 KiB

table#slostatustable {
width: 100%;
border-collapse: collapse;
}
table#slostatustable tr td {
border-top: 1px solid #ccc;
}
table#slostatustable tr td.statustext span { display: none; }
table#slostatustable tr.completed td.statustext span.completed { display: inline; }
table#slostatustable tr.onhold td.statustext span.onhold { display: inline; }
table#slostatustable tr.inprogress td.statustext span.inprogress { display: inline; }
table#slostatustable tr.failed td.statustext span.failed { display: inline; }
table#slostatustable tr td.icons img {
margin: 3px;
display: none;
}
table#slostatustable tr.completed td.icons img.completed { display: inline; }
table#slostatustable tr.onhold td.icons img.onhold { display: inline; }
table#slostatustable tr.inprogress td.icons img.inprogress { display: inline; }
table#slostatustable tr.failed td.icons img.failed { display: inline; }
iframe.hiddeniframe {
display: none;
}
/* From old CSS
div.allcompleted#interrupt {
display: none;
}
div#interrupt a:link {
color: #036;
border-bottom: 1px dotted #036;
text-decoration: none;
}
div#interrupt a:hover {
border-bottom: 1px solid #036;
}
div#interrupt {
display: block;
border: 3px solid #036;
background: #39F;
padding: 1em;
margin: .2em;
}
div#iscompleted {
display: none;
border: 3px solid #993;
background: #FF9;
padding: 1em;
margin: .2em;
}
div.allcompleted#iscompleted {
display: block ! important;
}
div.inprogress, div.loggedout {
background: #eee;
color: #444;
padding: .2em 1em;
margin: .2em;
}
div.inprogress {
border: 1px dotted #888;
}
div.loggedout {
border: 1px solid #888;
background: #9f9 ! important ;
}
iframe.hiddeniframe {
display: none;
}
*/
\ No newline at end of file
<?php <?php
/** /**
* This SAML 2.0 endpoint can receive incomming LogoutRequests. It will also send LogoutResponses, * This SAML 2.0 endpoint can receive incoming LogoutRequests. It will also send LogoutResponses,
* and LogoutRequests and also receive LogoutResponses. It is implemeting SLO at the SAML 2.0 IdP. * and LogoutRequests and also receive LogoutResponses. It is implemeting SLO at the SAML 2.0 IdP.
* *
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
...@@ -90,6 +90,8 @@ require_once(SimpleSAML_Utilities::resolvePath('libextinc') . '/xajax/xajax.inc. ...@@ -90,6 +90,8 @@ require_once(SimpleSAML_Utilities::resolvePath('libextinc') . '/xajax/xajax.inc.
*/ */
function updateslostatus() { function updateslostatus() {
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version) within updateslostatus() '); SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version) within updateslostatus() ');
$config = SimpleSAML_Configuration::getInstance(); $config = SimpleSAML_Configuration::getInstance();
...@@ -117,14 +119,19 @@ function updateslostatus() { ...@@ -117,14 +119,19 @@ function updateslostatus() {
$spname = is_array($name) ? $t->getTranslation($name) : $name; $spname = is_array($name) ? $t->getTranslation($name) : $name;
$objResponse->addAssign('e' . sha1($spentityid), "className", 'loggedout'); $objResponse->addScriptCall('slocompletesp', 'e' . sha1($spentityid));
$objResponse->addAssign('e' . sha1($spentityid), "innerHTML", 'Logging out from <strong>' . $spname . '</strong> successfully completed'); // $objResponse->addAssign('e' . sha1($spentityid), "className", 'loggedout');
// $objResponse->addAssign('e' . sha1($spentityid), "innerHTML", 'Logging out from <strong>' . $spname . '</strong> successfully completed');
} }
if ($session->sp_logout_completed() === TRUE) { if ($session->sp_logout_completed() === TRUE) {
$objResponse->addAssign('iscompleted', "className", 'allcompleted'); // $objResponse->addAssign('iscompleted', "className", 'allcompleted');
$objResponse->addAssign('interrupt', "className", 'allcompleted'); // $objResponse->addAssign('interrupt', "className", 'allcompleted');
$objResponse->addScriptCall('slocompleted');
/** /**
* Clean up session object to save storage. * Clean up session object to save storage.
...@@ -269,6 +276,7 @@ $session->dump_sp_sessions(); ...@@ -269,6 +276,7 @@ $session->dump_sp_sessions();
*/ */
$listofsps = $session->get_sp_list(); $listofsps = $session->get_sp_list();
$sparray = array(); $sparray = array();
$sparrayNoLogout = array();
foreach ($listofsps AS $spentityid) { foreach ($listofsps AS $spentityid) {
// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) { // ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
...@@ -276,20 +284,26 @@ foreach ($listofsps AS $spentityid) { ...@@ -276,20 +284,26 @@ foreach ($listofsps AS $spentityid) {
if($nameId === NULL) { if($nameId === NULL) {
$nameId = $session->getNameID(); $nameId = $session->getNameID();
} }
$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');
$spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote'); $spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote');
$name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid; $name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid;
$sparray[$spentityid] = array('url' => $url, 'name' => $name); 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);
}
} }
...@@ -396,8 +410,10 @@ if (array_key_exists('name', $spmeta)) $spname = $spmeta['name']; ...@@ -396,8 +410,10 @@ if (array_key_exists('name', $spmeta)) $spname = $spmeta['name'];
$et = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php'); $et = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
$et->data['header'] = 'SAML 2.0 IdP Ajax Logout'; $et->data['header'] = 'Global logout';
$et->data['sparray'] = $sparray; $et->data['sparray'] = $sparray;
$et->data['sparrayNoLogout'] = $sparrayNoLogout;
$et->data['logoutresponse'] = $logoutresponse; $et->data['logoutresponse'] = $logoutresponse;
$et->data['xajax'] = $xajax; $et->data['xajax'] = $xajax;
$et->data['requesterName'] = $spname; $et->data['requesterName'] = $spname;
......
...@@ -22,7 +22,7 @@ if (isset($session) ) { ...@@ -22,7 +22,7 @@ if (isset($session) ) {
$session->clean(); $session->clean();
} }
# sleep(max(0, rand(-5,15)));
if (isset($_GET['SAMLRequest'])) { if (isset($_GET['SAMLRequest'])) {
......
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