public function handleLogoutRequests($check_client = true, $allowed_clients = false)
{
phpCAS::traceBegin();
if (!$this->_isLogoutRequest()) {
phpCAS::trace("Not a logout request");
phpCAS::traceEnd();
return;
}
if (!$this->getChangeSessionID() && is_null($this->_signoutCallbackFunction)) {
phpCAS::trace("phpCAS can't handle logout requests if it is not allowed to change session_id.");
}
phpCAS::trace("Logout requested");
$decoded_logout_rq = urldecode($_POST['logoutRequest']);
phpCAS::trace("SAML REQUEST: " . $decoded_logout_rq);
$allowed = false;
if ($check_client) {
if (!$allowed_clients) {
$allowed_clients = array($this->_getServerHostname());
}
$client_ip = $_SERVER['REMOTE_ADDR'];
$client = gethostbyaddr($client_ip);
phpCAS::trace("Client: " . $client . "/" . $client_ip);
foreach ($allowed_clients as $allowed_client) {
if ($client == $allowed_client || $client_ip == $allowed_client) {
phpCAS::trace("Allowed client '" . $allowed_client . "' matches, logout request is allowed");
$allowed = true;
break;
} else {
phpCAS::trace("Allowed client '" . $allowed_client . "' does not match");
}
}
} else {
phpCAS::trace("No access control set");
$allowed = true;
}
// If Logout command is permitted proceed with the logout
if ($allowed) {
phpCAS::trace("Logout command allowed");
// Rebroadcast the logout request
if ($this->_rebroadcast && !isset($_POST['rebroadcast'])) {
$this->_rebroadcast(self::LOGOUT);
}
// Extract the ticket from the SAML Request
preg_match("|<samlp:SessionIndex>(.*)</samlp:SessionIndex>|", $decoded_logout_rq, $tick, PREG_OFFSET_CAPTURE, 3);
$wrappedSamlSessionIndex = preg_replace('|<samlp:SessionIndex>|', '', $tick[0][0]);
$ticket2logout = preg_replace('|</samlp:SessionIndex>|', '', $wrappedSamlSessionIndex);
phpCAS::trace("Ticket to logout: " . $ticket2logout);
// call the post-authenticate callback if registered.
if ($this->_signoutCallbackFunction) {
$args = $this->_signoutCallbackArgs;
array_unshift($args, $ticket2logout);
call_user_func_array($this->_signoutCallbackFunction, $args);
}
// If phpCAS is managing the session_id, destroy session thanks to
// session_id.
if ($this->getChangeSessionID()) {
$session_id = preg_replace('/[^a-zA-Z0-9\\-]/', '', $ticket2logout);
phpCAS::trace("Session id: " . $session_id);
// destroy a possible application session created before phpcas
if (session_id() !== "") {
session_unset();
session_destroy();
}
// fix session ID
session_id($session_id);
$_COOKIE[session_name()] = $session_id;
$_GET[session_name()] = $session_id;
// Overwrite session
session_start();
session_unset();
session_destroy();
phpCAS::trace("Session " . $session_id . " destroyed");
}
} else {
phpCAS::error("Unauthorized logout request from client '" . $client . "'");
phpCAS::trace("Unauthorized logout request from client '" . $client . "'");
}
flush();
phpCAS::traceExit();
throw new CAS_GracefullTerminationException();
}