From f71b08f32dd3ef8c6427a1d741081d49a6a47357 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Mon, 10 Nov 2008 13:01:32 +0000 Subject: [PATCH] Auth/{Source,Default}: add support for logout callbacks, for receiving external logout notifications. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@984 44740490-163a-0410-bde0-09ae8108e29a --- lib/SimpleSAML/Auth/Default.php | 29 +++++++++++++ lib/SimpleSAML/Auth/Source.php | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/lib/SimpleSAML/Auth/Default.php b/lib/SimpleSAML/Auth/Default.php index 5f620a341..2f35a96a3 100644 --- a/lib/SimpleSAML/Auth/Default.php +++ b/lib/SimpleSAML/Auth/Default.php @@ -37,6 +37,10 @@ class SimpleSAML_Auth_Default { 'SimpleSAML_Auth_Default.ErrorURL' => $errorURL, 'LoginCompletedHandler' => array(get_class(), 'loginCompleted'), 'LoginFailedHandler' => array(get_class(), 'loginFailed'), + 'LogoutCallback' => array(get_class(), 'logoutCallback'), + 'LogoutCallbackState' => array( + 'SimpleSAML_Auth_Default.logoutSource' => $authId, + ), ); if (array_key_exists('SPMetadata', $hints)) { @@ -163,6 +167,31 @@ class SimpleSAML_Auth_Default { SimpleSAML_Utilities::redirect($returnURL); } + + /** + * Called when the authentication source receives an external logout request. + * + * @param array $state State array for the logout operation. + */ + public static function logoutCallback($state) { + assert('is_array($state)'); + assert('array_key_exists("SimpleSAML_Auth_Default.logoutSource", $state)'); + + $source = $state['SimpleSAML_Auth_Default.logoutSource']; + + $session = SimpleSAML_Session::getInstance(); + $authId = $session->getAuthority(); + + if ($authId !== $source) { + SimpleSAML_Logger::warning('Received logout from different authentication source ' . + 'than the current. Current is ' . var_export($authId, TRUE) . + '. Logout source is ' . var_export($source, TRUE) . '.'); + return; + } + + $session->doLogout(); + } + } ?> \ No newline at end of file diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php index c76951852..f0a0c948b 100644 --- a/lib/SimpleSAML/Auth/Source.php +++ b/lib/SimpleSAML/Auth/Source.php @@ -178,6 +178,81 @@ abstract class SimpleSAML_Auth_Source { return self::parseAuthSource($authId, $authConfig); } + + /** + * Add a logout callback association. + * + * This function adds a logout callback association, which allows us to initiate + * a logout later based on the $assoc-value. + * + * Note that logout-associations exists per authentication source. A logout association + * from one authentication source cannot be called from a different authentication source. + * + * @param string $assoc The identifier for this logout association. + * @param array $state The state array passed to the authenticate-function. + */ + protected function addLogoutCallback($assoc, $state) { + assert('is_string($assoc)'); + assert('is_array($state)'); + + if (!array_key_exists('LogoutCallback', $state)) { + /* The authentication requester doesn't have a logout callback. */ + return; + } + $callback = $state['LogoutCallback']; + + if (array_key_exists('LogoutCallbackState', $state)) { + $callbackState = $state['LogoutCallbackState']; + } else { + $callbackState = array(); + } + + $id = strlen($this->authId) . ':' . $this->authId . $assoc; + + $data = array( + 'callback' => $callback, + 'state' => $callbackState, + ); + + + $session = SimpleSAML_Session::getInstance(); + $session->setData('SimpleSAML_Auth_Source.LogoutCallbacks', $id, $data, + SimpleSAML_Session::DATA_TIMEOUT_LOGOUT); + } + + + /** + * Call a logout callback based on association. + * + * This function calls a logout callback based on an association saved with + * addLogoutCallback(...). + * + * This function always returns. + * + * @param string $assoc The logout association which should be called. + */ + protected function callLogoutCallback($assoc) { + assert('is_string($assoc)'); + + $id = strlen($this->authId) . ':' . $this->authId . $assoc; + + $session = SimpleSAML_Session::getInstance(); + + $data = $session->getData('SimpleSAML_Auth_Source.LogoutCallbacks', $id); + if ($data === NULL) { + return; + } + + assert('is_array($data)'); + assert('array_key_exists("callback", $data)'); + assert('array_key_exists("state", $data)'); + + $callback = $data['callback']; + $callbackState = $data['state']; + + call_user_func($callback, $callbackState); + } + } ?> \ No newline at end of file -- GitLab