ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
IdP.php
Go to the documentation of this file.
1 <?php
2 
3 
12 {
13 
19  private static $idpCache = array();
20 
21 
27  private $id;
28 
29 
39 
40 
46  private $config;
47 
48 
54  private $authSource;
55 
56 
64  private function __construct($id)
65  {
66  assert('is_string($id)');
67 
68  $this->id = $id;
69 
72 
73  if (substr($id, 0, 6) === 'saml2:') {
74  if (!$globalConfig->getBoolean('enable.saml20-idp', false)) {
75  throw new SimpleSAML_Error_Exception('enable.saml20-idp disabled in config.php.');
76  }
77  $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'saml20-idp-hosted');
78  } elseif (substr($id, 0, 6) === 'saml1:') {
79  if (!$globalConfig->getBoolean('enable.shib13-idp', false)) {
80  throw new SimpleSAML_Error_Exception('enable.shib13-idp disabled in config.php.');
81  }
82  $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'shib13-idp-hosted');
83  } elseif (substr($id, 0, 5) === 'adfs:') {
84  if (!$globalConfig->getBoolean('enable.adfs-idp', false)) {
85  throw new SimpleSAML_Error_Exception('enable.adfs-idp disabled in config.php.');
86  }
87  $this->config = $metadata->getMetaDataConfig(substr($id, 5), 'adfs-idp-hosted');
88 
89  try {
90  // this makes the ADFS IdP use the same SP associations as the SAML 2.0 IdP
91  $saml2EntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
92  $this->associationGroup = 'saml2:'.$saml2EntityId;
93  } catch (Exception $e) {
94  // probably no SAML 2 IdP configured for this host. Ignore the error
95  }
96  } else {
97  assert(false);
98  }
99 
100  if ($this->associationGroup === null) {
101  $this->associationGroup = $this->id;
102  }
103 
104  $auth = $this->config->getString('auth');
105  if (SimpleSAML_Auth_Source::getById($auth) !== null) {
106  $this->authSource = new \SimpleSAML\Auth\Simple($auth);
107  } else {
108  throw new SimpleSAML_Error_Exception('No such "'.$auth.'" auth source found.');
109  }
110  }
111 
112 
118  public function getId()
119  {
120  return $this->id;
121  }
122 
123 
131  public static function getById($id)
132  {
133  assert('is_string($id)');
134 
135  if (isset(self::$idpCache[$id])) {
136  return self::$idpCache[$id];
137  }
138 
139  $idp = new self($id);
140  self::$idpCache[$id] = $idp;
141  return $idp;
142  }
143 
144 
152  public static function getByState(array &$state)
153  {
154  assert('isset($state["core:IdP"])');
155 
156  return self::getById($state['core:IdP']);
157  }
158 
159 
165  public function getConfig()
166  {
167  return $this->config;
168  }
169 
170 
178  public function getSPName($assocId)
179  {
180  assert('is_string($assocId)');
181 
182  $prefix = substr($assocId, 0, 4);
183  $spEntityId = substr($assocId, strlen($prefix) + 1);
185 
186  if ($prefix === 'saml') {
187  try {
188  $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
189  } catch (Exception $e) {
190  try {
191  $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'shib13-sp-remote');
192  } catch (Exception $e) {
193  return null;
194  }
195  }
196  } else {
197  if ($prefix === 'adfs') {
198  $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'adfs-sp-remote');
199  } else {
200  return null;
201  }
202  }
203 
204  if ($spMetadata->hasValue('name')) {
205  return $spMetadata->getLocalizedString('name');
206  } elseif ($spMetadata->hasValue('OrganizationDisplayName')) {
207  return $spMetadata->getLocalizedString('OrganizationDisplayName');
208  } else {
209  return array('en' => $spEntityId);
210  }
211  }
212 
213 
220  {
221  assert('isset($association["id"])');
222  assert('isset($association["Handler"])');
223 
224  $association['core:IdP'] = $this->id;
225 
227  $session->addAssociation($this->associationGroup, $association);
228  }
229 
230 
236  public function getAssociations()
237  {
239  return $session->getAssociations($this->associationGroup);
240  }
241 
242 
249  {
250  assert('is_string($assocId)');
251 
253  $session->terminateAssociation($this->associationGroup, $assocId);
254  }
255 
256 
262  public function isAuthenticated()
263  {
264  return $this->authSource->isAuthenticated();
265  }
266 
267 
273  public static function postAuthProc(array $state)
274  {
275  assert('is_callable($state["Responder"])');
276 
277  if (isset($state['core:SP'])) {
279  $session->setData(
280  'core:idp-ssotime',
281  $state['core:IdP'].';'.$state['core:SP'],
282  time(),
284  );
285  }
286 
287  call_user_func($state['Responder'], $state);
288  assert('FALSE');
289  }
290 
291 
299  public static function postAuth(array $state)
300  {
302 
303  if (!$idp->isAuthenticated()) {
304  throw new SimpleSAML_Error_Exception('Not authenticated.');
305  }
306 
307  $state['Attributes'] = $idp->authSource->getAttributes();
308 
309  if (isset($state['SPMetadata'])) {
310  $spMetadata = $state['SPMetadata'];
311  } else {
312  $spMetadata = array();
313  }
314 
315  if (isset($state['core:SP'])) {
317  $previousSSOTime = $session->getData('core:idp-ssotime', $state['core:IdP'].';'.$state['core:SP']);
318  if ($previousSSOTime !== null) {
319  $state['PreviousSSOTimestamp'] = $previousSSOTime;
320  }
321  }
322 
323  $idpMetadata = $idp->getConfig()->toArray();
324 
326 
327  $state['ReturnCall'] = array('SimpleSAML_IdP', 'postAuthProc');
328  $state['Destination'] = $spMetadata;
329  $state['Source'] = $idpMetadata;
330 
331  $pc->processState($state);
332 
333  self::postAuthProc($state);
334  }
335 
336 
346  private function authenticate(array &$state)
347  {
348  if (isset($state['isPassive']) && (bool) $state['isPassive']) {
349  throw new SimpleSAML_Error_NoPassive('Passive authentication not supported.');
350  }
351 
352  $this->authSource->login($state);
353  }
354 
355 
368  private function reauthenticate(array &$state)
369  {
370  $sourceImpl = $this->authSource->getAuthSource();
371  if ($sourceImpl === null) {
372  throw new SimpleSAML_Error_Exception('No such auth source defined.');
373  }
374 
375  $sourceImpl->reauthenticate($state);
376  }
377 
378 
385  {
386  assert('isset($state["Responder"])');
387 
388  $state['core:IdP'] = $this->id;
389 
390  if (isset($state['SPMetadata']['entityid'])) {
391  $spEntityId = $state['SPMetadata']['entityid'];
392  } elseif (isset($state['SPMetadata']['entityID'])) {
393  $spEntityId = $state['SPMetadata']['entityID'];
394  } else {
395  $spEntityId = null;
396  }
397  $state['core:SP'] = $spEntityId;
398 
399  // first, check whether we need to authenticate the user
400  if (isset($state['ForceAuthn']) && (bool) $state['ForceAuthn']) {
401  // force authentication is in effect
402  $needAuth = true;
403  } else {
404  $needAuth = !$this->isAuthenticated();
405  }
406 
407  $state['IdPMetadata'] = $this->getConfig()->toArray();
408  $state['ReturnCallback'] = array('SimpleSAML_IdP', 'postAuth');
409 
410  try {
411  if ($needAuth) {
412  $this->authenticate($state);
413  assert('FALSE');
414  } else {
415  $this->reauthenticate($state);
416  }
417  $this->postAuth($state);
418  } catch (SimpleSAML_Error_Exception $e) {
420  } catch (Exception $e) {
423  }
424  }
425 
426 
434  public function getLogoutHandler()
435  {
436  // find the logout handler
437  $logouttype = $this->getConfig()->getString('logouttype', 'traditional');
438  switch ($logouttype) {
439  case 'traditional':
440  $handler = 'SimpleSAML\IdP\TraditionalLogoutHandler';
441  break;
442  case 'iframe':
443  $handler = 'SimpleSAML\IdP\IFrameLogoutHandler';
444  break;
445  default:
446  throw new SimpleSAML_Error_Exception('Unknown logout handler: '.var_export($logouttype, true));
447  }
448 
449  return new $handler($this);
450  }
451 
452 
460  public function finishLogout(array &$state)
461  {
462  assert('isset($state["Responder"])');
463 
465  call_user_func($state['Responder'], $idp, $state);
466  assert('false');
467  }
468 
469 
480  {
481  assert('isset($state["Responder"])');
482  assert('is_string($assocId) || is_null($assocId)');
483 
484  $state['core:IdP'] = $this->id;
485  $state['core:TerminatedAssocId'] = $assocId;
486 
487  if ($assocId !== null) {
490  $session->deleteData('core:idp-ssotime', $this->id.':'.$state['saml:SPEntityId']);
491  }
492 
493  // terminate the local session
494  $id = SimpleSAML_Auth_State::saveState($state, 'core:Logout:afterbridge');
495  $returnTo = SimpleSAML\Module::getModuleURL('core/idp/resumelogout.php', array('id' => $id));
496 
497  $this->authSource->logout($returnTo);
498 
499  $handler = $this->getLogoutHandler();
500  $handler->startLogout($state, $assocId);
501  assert('false');
502  }
503 
504 
515  {
516  assert('is_string($assocId)');
517  assert('is_string($relayState) || is_null($relayState)');
518 
520  $session->deleteData('core:idp-ssotime', $this->id.';'.substr($assocId, strpos($assocId, ':') + 1));
521 
522  $handler = $this->getLogoutHandler();
523  $handler->onResponse($assocId, $relayState, $error);
524 
525  assert('false');
526  }
527 
528 
536  public function doLogoutRedirect($url)
537  {
538  assert('is_string($url)');
539 
540  $state = array(
541  'Responder' => array('SimpleSAML_IdP', 'finishLogoutRedirect'),
542  'core:Logout:URL' => $url,
543  );
544 
545  $this->handleLogoutRequest($state, null);
546  assert('false');
547  }
548 
549 
559  {
560  assert('isset($state["core:Logout:URL"])');
561 
562  \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['core:Logout:URL']);
563  assert('false');
564  }
565 }
handleLogoutRequest(array &$state, $assocId)
Process a logout request.
Definition: IdP.php:479
doLogoutRedirect($url)
Log out, then redirect to a URL.
Definition: IdP.php:536
handleAuthenticationRequest(array &$state)
Process authentication requests.
Definition: IdP.php:384
$auth
Definition: metadata.php:48
static getMetadataHandler()
This function retrieves the current instance of the metadata handler.
if(!isset($_REQUEST['ReturnTo'])) $returnTo
Definition: authpage.php:16
static getByState(array &$state)
Retrieve the IdP "owning" the state.
Definition: IdP.php:152
static $idpCache
Definition: IdP.php:19
isAuthenticated()
Is the current user authenticated?
Definition: IdP.php:262
static getById($id)
Retrieve an IdP by ID.
Definition: IdP.php:131
static throwException($state, SimpleSAML_Error_Exception $exception)
Throw exception to the state exception handler.
Definition: State.php:343
reauthenticate(array &$state)
Re-authenticate the user.
Definition: IdP.php:368
$spEntityId
$session
static redirectTrustedURL($url, $parameters=array())
This function redirects to the specified URL without performing any security checks.
Definition: HTTP.php:962
$spMetadata
$metadata['__DYNAMIC:1__']
handleLogoutResponse($assocId, $relayState, SimpleSAML_Error_Exception $error=null)
Process a logout response.
Definition: IdP.php:514
Class SimpleSAML_Error_NoPassive.
Definition: NoPassive.php:12
finishLogout(array &$state)
Finish the logout operation.
Definition: IdP.php:460
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
Definition: Module.php:303
addAssociation(array $association)
Add an SP association.
Definition: IdP.php:219
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$error
Definition: Error.php:17
$relayState
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
getLogoutHandler()
Find the logout handler of this IdP.
Definition: IdP.php:434
getConfig()
Retrieve the configuration for this IdP.
Definition: IdP.php:165
static finishLogoutRedirect(SimpleSAML_IdP $idp, array $state)
Redirect to a URL after logout.
Definition: IdP.php:558
terminateAssociation($assocId)
Remove an SP association.
Definition: IdP.php:248
Create styles array
The data for the language used.
getId()
Retrieve the ID of this IdP.
Definition: IdP.php:118
authenticate(array &$state)
Authenticate the user.
Definition: IdP.php:346
$globalConfig
getSPName($assocId)
Get SP name.
Definition: IdP.php:178
if(!isset($associations[$assocId])) $association
$idp
Definition: prp.php:13
$associationGroup
Definition: IdP.php:38
$idpMetadata
if(!isset($_REQUEST['association'])) $assocId
__construct($id)
Initialize an IdP.
Definition: IdP.php:64
$url
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
getAssociations()
Retrieve list of SP associations.
Definition: IdP.php:236
static getById($authId, $type=null)
Retrieve authentication source.
Definition: Source.php:324
$handler
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:243
static saveState(&$state, $stage, $rawId=false)
Save the state.
Definition: State.php:194
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
static postAuthProc(array $state)
Called after authproc has run.
Definition: IdP.php:273
static postAuth(array $state)
The user is authenticated.
Definition: IdP.php:299