ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Source.php
Go to the documentation of this file.
1 <?php
2 
4 
13 abstract class SimpleSAML_Auth_Source
14 {
15 
16 
23  protected $authId;
24 
25 
35  public function __construct($info, &$config)
36  {
37  assert(is_array($info));
38  assert(is_array($config));
39 
40  assert(array_key_exists('AuthId', $info));
41  $this->authId = $info['AuthId'];
42  }
43 
44 
53  public static function getSourcesOfType($type)
54  {
55  assert(is_string($type));
56 
57  $config = SimpleSAML_Configuration::getConfig('authsources.php');
58 
59  $ret = array();
60 
61  $sources = $config->getOptions();
62  foreach ($sources as $id) {
63  $source = $config->getArray($id);
64 
65  self::validateSource($source, $id);
66 
67  if ($source[0] !== $type) {
68  continue;
69  }
70 
71  $ret[] = self::parseAuthSource($id, $source);
72  }
73 
74  return $ret;
75  }
76 
77 
83  public function getAuthId()
84  {
85  return $this->authId;
86  }
87 
88 
103  abstract public function authenticate(&$state);
104 
105 
114  public function reauthenticate(array &$state)
115  {
116  assert(isset($state['ReturnCallback']));
117 
118  // the default implementation just copies over the previous authentication data
120  $data = $session->getAuthState($this->authId);
121  foreach ($data as $k => $v) {
122  $state[$k] = $v;
123  }
124  }
125 
126 
136  public static function completeAuth(&$state)
137  {
138  assert(is_array($state));
139  assert(array_key_exists('LoginCompletedHandler', $state));
140 
142 
143  $func = $state['LoginCompletedHandler'];
144  assert(is_callable($func));
145 
146  call_user_func($func, $state);
147  assert(false);
148  }
149 
150 
164  public function initLogin($return, $errorURL = null, array $params = array())
165  {
166  assert(is_string($return) || is_array($return));
167  assert(is_string($errorURL) || $errorURL === null);
168 
169  $state = array_merge($params, array(
170  'SimpleSAML_Auth_Default.id' => $this->authId, // TODO: remove in 2.0
171  'SimpleSAML_Auth_Source.id' => $this->authId,
172  'SimpleSAML_Auth_Default.Return' => $return, // TODO: remove in 2.0
173  'SimpleSAML_Auth_Source.Return' => $return,
174  'SimpleSAML_Auth_Default.ErrorURL' => $errorURL, // TODO: remove in 2.0
175  'SimpleSAML_Auth_Source.ErrorURL' => $errorURL,
176  'LoginCompletedHandler' => array(get_class(), 'loginCompleted'),
177  'LogoutCallback' => array(get_class(), 'logoutCallback'),
178  'LogoutCallbackState' => array(
179  'SimpleSAML_Auth_Default.logoutSource' => $this->authId, // TODO: remove in 2.0
180  'SimpleSAML_Auth_Source.logoutSource' => $this->authId,
181  ),
182  ));
183 
184  if (is_string($return)) {
185  $state['SimpleSAML_Auth_Default.ReturnURL'] = $return; // TODO: remove in 2.0
186  $state['SimpleSAML_Auth_Source.ReturnURL'] = $return;
187  }
188 
189  if ($errorURL !== null) {
191  }
192 
193  try {
194  $this->authenticate($state);
195  } catch (SimpleSAML_Error_Exception $e) {
197  } catch (Exception $e) {
200  }
201  self::loginCompleted($state);
202  }
203 
204 
212  public static function loginCompleted($state)
213  {
214  assert(is_array($state));
215  assert(array_key_exists('SimpleSAML_Auth_Source.Return', $state));
216  assert(array_key_exists('SimpleSAML_Auth_Source.id', $state));
217  assert(array_key_exists('Attributes', $state));
218  assert(!array_key_exists('LogoutState', $state) || is_array($state['LogoutState']));
219 
220  $return = $state['SimpleSAML_Auth_Source.Return'];
221 
222  // save session state
224  $authId = $state['SimpleSAML_Auth_Source.id'];
226 
227  if (is_string($return)) { // redirect...
229  } else {
230  call_user_func($return, $state);
231  }
232  assert(false);
233  }
234 
235 
249  public function logout(&$state)
250  {
251  assert(is_array($state));
252  // default logout handler which doesn't do anything
253  }
254 
255 
265  public static function completeLogout(&$state)
266  {
267  assert(is_array($state));
268  assert(array_key_exists('LogoutCompletedHandler', $state));
269 
271 
272  $func = $state['LogoutCompletedHandler'];
273  assert(is_callable($func));
274 
275  call_user_func($func, $state);
276  assert(false);
277  }
278 
279 
292  private static function parseAuthSource($authId, $config)
293  {
294  assert(is_string($authId));
295  assert(is_array($config));
296 
297  self::validateSource($config, $authId);
298 
299  $id = $config[0];
300  $info = array('AuthId' => $authId);
301  $authSource = null;
302 
303  unset($config[0]);
304 
305  try {
306  // Check whether or not there's a factory responsible for instantiating our Auth Source instance
307  $factoryClass = SimpleSAML\Module::resolveClass($id, 'Auth_Source_Factory', 'SimpleSAML\Auth\SourceFactory');
308 
310  $factory = new $factoryClass;
311  $authSource = $factory->create($info, $config);
312  } catch (Exception $e) {
313  // If not, instantiate the Auth Source here
314  $className = SimpleSAML\Module::resolveClass($id, 'Auth_Source', 'SimpleSAML_Auth_Source');
315  $authSource = new $className($info, $config);
316  }
317 
318  return $authSource;
319  }
320 
321 
340  public static function getById($authId, $type = null)
341  {
342  assert(is_string($authId));
343  assert($type === null || is_string($type));
344 
345  // for now - load and parse config file
346  $config = SimpleSAML_Configuration::getConfig('authsources.php');
347 
348  $authConfig = $config->getArray($authId, null);
349  if ($authConfig === null) {
350  if ($type !== null) {
351  throw new SimpleSAML_Error_Exception(
352  'No authentication source with id '.
353  var_export($authId, true).' found.'
354  );
355  }
356  return null;
357  }
358 
359  $ret = self::parseAuthSource($authId, $authConfig);
360 
361  if ($type === null || $ret instanceof $type) {
362  return $ret;
363  }
364 
365  // the authentication source doesn't have the correct type
366  throw new SimpleSAML_Error_Exception(
367  'Invalid type of authentication source '.
368  var_export($authId, true).'. Was '.var_export(get_class($ret), true).
369  ', should be '.var_export($type, true).'.'
370  );
371  }
372 
373 
379  public static function logoutCallback($state)
380  {
381  assert(is_array($state));
382  assert(array_key_exists('SimpleSAML_Auth_Source.logoutSource', $state));
383 
384  $source = $state['SimpleSAML_Auth_Source.logoutSource'];
385 
387  if (!$session->isValid($source)) {
389  'Received logout from an invalid authentication source '.
390  var_export($source, true)
391  );
392 
393  return;
394  }
395  $session->doLogout($source);
396  }
397 
398 
411  protected function addLogoutCallback($assoc, $state)
412  {
413  assert(is_string($assoc));
414  assert(is_array($state));
415 
416  if (!array_key_exists('LogoutCallback', $state)) {
417  // the authentication requester doesn't have a logout callback
418  return;
419  }
420  $callback = $state['LogoutCallback'];
421 
422  if (array_key_exists('LogoutCallbackState', $state)) {
423  $callbackState = $state['LogoutCallbackState'];
424  } else {
425  $callbackState = array();
426  }
427 
428  $id = strlen($this->authId).':'.$this->authId.$assoc;
429 
430  $data = array(
431  'callback' => $callback,
432  'state' => $callbackState,
433  );
434 
436  $session->setData(
437  'SimpleSAML_Auth_Source.LogoutCallbacks',
438  $id,
439  $data,
441  );
442  }
443 
444 
455  protected function callLogoutCallback($assoc)
456  {
457  assert(is_string($assoc));
458 
459  $id = strlen($this->authId).':'.$this->authId.$assoc;
460 
462 
463  $data = $session->getData('SimpleSAML_Auth_Source.LogoutCallbacks', $id);
464  if ($data === null) {
465  // FIXME: fix for IdP-first flow (issue 397) -> reevaluate logout callback infrastructure
466  $session->doLogout($this->authId);
467 
468  return;
469  }
470 
471  assert(is_array($data));
472  assert(array_key_exists('callback', $data));
473  assert(array_key_exists('state', $data));
474 
475  $callback = $data['callback'];
476  $callbackState = $data['state'];
477 
478  $session->deleteData('SimpleSAML_Auth_Source.LogoutCallbacks', $id);
479  call_user_func($callback, $callbackState);
480  }
481 
482 
488  public static function getSources()
489  {
491 
492  return $config->getOptions();
493  }
494 
495 
504  protected static function validateSource($source, $id)
505  {
506  if (!array_key_exists(0, $source) || !is_string($source[0])) {
507  throw new Exception(
508  'Invalid authentication source \''.$id.
509  '\': First element must be a string which identifies the authentication source.'
510  );
511  }
512  }
513 }
const EXCEPTION_HANDLER_URL
The index in the state array which contains the exception handler URL.
Definition: State.php:63
$config
Definition: bootstrap.php:15
logout(&$state)
Log out from this authentication source.
Definition: Source.php:249
$type
callLogoutCallback($assoc)
Call a logout callback based on association.
Definition: Source.php:455
static throwException($state, SimpleSAML_Error_Exception $exception)
Throw exception to the state exception handler.
Definition: State.php:343
$session
static loginCompleted($state)
Called when a login operation has finished.
Definition: Source.php:212
$factory
Definition: metadata.php:43
if(!array_key_exists('StateId', $_REQUEST)) $id
getAuthId()
Retrieve the ID of this authentication source.
Definition: Source.php:83
static redirectTrustedURL($url, $parameters=array())
This function redirects to the specified URL without performing any security checks.
Definition: HTTP.php:959
static completeLogout(&$state)
Complete logout.
Definition: Source.php:265
authenticate(&$state)
Process a request.
static validateSource($source, $id)
Make sure that the first element of an auth source is its identifier.
Definition: Source.php:504
static logoutCallback($state)
Called when the authentication source receives an external logout request.
Definition: Source.php:379
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
const DATA_TIMEOUT_SESSION_END
This is a timeout value for setData, which indicates that the data should never be deleted...
Definition: Session.php:26
static warning($string)
Definition: Logger.php:177
__construct($info, &$config)
Constructor for an authentication source.
Definition: Source.php:35
addLogoutCallback($assoc, $state)
Add a logout callback association.
Definition: Source.php:411
static getConfig($filename='config.php', $configSet='simplesaml')
Load a configuration file from a configuration set.
static deleteState(&$state)
Delete state.
Definition: State.php:319
static getPersistentAuthData(array $state)
Get the persistent authentication state from the state array.
Definition: State.php:103
$ret
Definition: parser.php:6
reauthenticate(array &$state)
Reauthenticate an user.
Definition: Source.php:114
static getOptionalConfig($filename='config.php', $configSet='simplesaml')
Load a configuration file from a configuration set.
static completeAuth(&$state)
Complete authentication.
Definition: Source.php:136
$source
Definition: linkback.php:22
static resolveClass($id, $type, $subclass=null)
Resolve module class.
Definition: Module.php:169
static getSources()
Retrieve list of authentication sources.
Definition: Source.php:488
initLogin($return, $errorURL=null, array $params=array())
Start authentication.
Definition: Source.php:164
static getById($authId, $type=null)
Retrieve authentication source.
Definition: Source.php:340
$info
Definition: index.php:5
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:241
static getSourcesOfType($type)
Get sources of a specific type.
Definition: Source.php:53
$data
Definition: bench.php:6