<?php /** * Implements the default behaviour for authentication. * * This class contains an implementation for default behaviour when authenticating. It will * save the session information it got from the authentication client in the users session. * * @author Olav Morken, UNINETT AS. * @package simpleSAMLphp * @version $Id$ */ class SimpleSAML_Auth_Default { /** * Start authentication. * * This function never returns. * * @param string $authId The identifier of the authentication source. * @param string $returnURL The URL we should direct the user to after authentication. * @param string|NULL $errorURL The URL we should direct the user to after failed authentication. * Can be NULL, in which case a standard error page will be shown. * @param array $hints Extra information about the login. Different authentication requestors may * provide different information. Optional, will default to an empty array. */ public static function initLogin($authId, $returnURL, $errorURL = NULL, $hints = array()) { assert('is_string($authId)'); assert('is_string($returnURL)'); assert('is_string($errorURL) || is_null($errorURL)'); assert('is_array($hints)'); $state = array( 'SimpleSAML_Auth_Default.id' => $authId, 'SimpleSAML_Auth_Default.ReturnURL' => $returnURL, '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)) { $state['SPMetadata'] = $hints['SPMetadata']; } if (array_key_exists('IdPMetadata', $hints)) { $state['IdPMetadata'] = $hints['IdPMetadata']; } if (array_key_exists(SimpleSAML_Auth_State::RESTART, $hints)) { $state[SimpleSAML_Auth_State::RESTART] = $hints[SimpleSAML_Auth_State::RESTART]; } $as = SimpleSAML_Auth_Source::getById($authId); if ($as === NULL) { throw new Exception('Invalid authentication source: ' . $authId); } $as->authenticate($state); self::loginCompleted($state); } /** * Called when a login operation has finished. * * @param array $state The state after the login. */ public static function loginCompleted($state) { assert('is_array($state)'); assert('array_key_exists("SimpleSAML_Auth_Default.ReturnURL", $state)'); assert('array_key_exists("SimpleSAML_Auth_Default.id", $state)'); assert('array_key_exists("Attributes", $state)'); assert('!array_key_exists("LogoutState", $state) || is_array($state["LogoutState"])'); $returnURL = $state['SimpleSAML_Auth_Default.ReturnURL']; /* Save session state. */ $session = SimpleSAML_Session::getInstance(); $session->doLogin($state['SimpleSAML_Auth_Default.id']); $session->setAttributes($state['Attributes']); if(array_key_exists('Expires', $state)) { $session->setSessionDuration($state['Expires'] - time()); } if (array_key_exists('LogoutState', $state)) { $session->setLogoutState($state['LogoutState']); } /* Redirect... */ SimpleSAML_Utilities::redirect($returnURL); } /** * Called when a login operation fails. * * @param array $state The state array. * @param string $statusCode A status code, in the form of an URI, which indicates why the login failed. * @param string $statusMessage A text which describes why the login failed. */ public static function loginFailed($state, $statusCode, $statusMessage) { assert('is_array($state)'); assert('array_key_exists("SimpleSAML_Auth_Default.ErrorURL", $state)'); assert('is_string($statusCode)'); assert('is_string($statusMessage)'); $url = $state['SimpleSAML_Auth_Default.ErrorURL']; if ($url === NULL) { /* We don't have an error handler. Show an error page. */ SimpleSAML_Utilities::fatalError($session->getTrackID(), 'RESPONSESTATUSNOSUCCESS', new Exception('StatusCode = \'' . $statusCode . '\'; StatusMessage = \'' . $statusMessage . '\';')); } $info = array('StatusCode' => $statusCode, 'StatusMessage' => $statusMessage); /* Redirect... */ SimpleSAML_Utilities::redirect($url, $info); } /** * Start logout. * * This function starts a logout operation from the current authentication source. This function * never returns. * * @param string $returnURL The URL we should redirect the user to after logging out. */ public static function initLogout($returnURL) { assert('is_string($returnURL)'); $session = SimpleSAML_Session::getInstance(); $state = $session->getLogoutState(); $authId = $session->getAuthority(); $session->doLogout(); $state['SimpleSAML_Auth_Default.ReturnURL'] = $returnURL; $state['LogoutCompletedHandler'] = array(get_class(), 'logoutCompleted'); $as = SimpleSAML_Auth_Source::getById($authId); if ($as === NULL) { /* The authority wasn't an authentication source... */ self::logoutCompleted($state); } $as->logout($state); self::logoutCompleted($state); } /** * Called when logout operation completes. * * This function never returns. * * @param array $state The state after the logout. */ public static function logoutCompleted($state) { assert('is_array($state)'); assert('array_key_exists("SimpleSAML_Auth_Default.ReturnURL", $state)'); $returnURL = $state['SimpleSAML_Auth_Default.ReturnURL']; /* Redirect... */ 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(); } } ?>