ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilAuthFrontend.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
12{
13 const MIG_EXTERNAL_ACCOUNT = 'mig_ext_account';
14 const MIG_TRIGGER_AUTHMODE = 'mig_trigger_auth_mode';
15 const MIG_DESIRED_AUTHMODE = 'mig_desired_auth_mode';
16
17 private $logger = null;
18 private $credentials = null;
19 private $status = null;
20 private $providers = array();
21 private $auth_session = null;
22
23 private $authenticated = false;
24
31 {
32 $this->logger = ilLoggerFactory::getLogger('auth');
33
34 $this->auth_session = $session;
35 $this->credentials = $credentials;
36 $this->status = $status;
37 $this->providers = $providers;
38 }
39
44 public function getAuthSession()
45 {
47 }
48
53 public function getCredentials()
54 {
55 return $this->credentials;
56 }
57
62 public function getProviders()
63 {
64 return $this->providers;
65 }
66
70 public function getStatus()
71 {
72 return $this->status;
73 }
74
78 public function resetStatus()
79 {
80 $this->getStatus()->setStatus(ilAuthStatus::STATUS_UNDEFINED);
81 $this->getStatus()->setReason('');
82 $this->getStatus()->setAuthenticatedUserId(0);
83 }
84
89 public function getLogger()
90 {
91 return $this->logger;
92 }
93
102 public function migrateAccount(ilAuthSession $session)
103 {
104 if(!$session->isAuthenticated())
105 {
106 $this->getLogger()->warning('Desired user account is not authenticated');
107 return false;
108 }
109 include_once './Services/Object/classes/class.ilObjectFactory.php';
110 $user_factory = new ilObjectFactory();
111 $user = $user_factory->getInstanceByObjId($session->getUserId(), false);
112
113 if(!$user instanceof ilObjUser)
114 {
115 $this->getLogger()->info('Cannot instanitate user account for account migration: ' . $session->getUserId());
116 return false;
117 }
118
119 $user->setAuthMode(ilSession::get(static::MIG_DESIRED_AUTHMODE));
120
121 $this->getLogger()->debug('new auth mode is: ' . ilSession::get(self::MIG_DESIRED_AUTHMODE));
122
123 $user->setExternalAccount(ilSession::get(static::MIG_EXTERNAL_ACCOUNT));
124 $user->update();
125
126 foreach($this->getProviders() as $provider)
127 {
129 {
130 $this->logger->warning('Provider: ' . get_class($provider) .' does not support account migration.');
131 throw new InvalidArgumentException('Invalid auth provider given.');
132 }
133 $this->getCredentials()->setUsername(ilSession::get(static::MIG_EXTERNAL_ACCOUNT));
134 $provider->migrateAccount($this->getStatus());
135 switch($this->getStatus()->getStatus())
136 {
138 return $this->handleAuthenticationSuccess($provider);
139
140 }
141 }
142 return $this->handleAuthenticationFail();
143 }
144
148 public function migrateAccountNew()
149 {
150 foreach($this->providers as $provider)
151 {
153 {
154 $this->logger->warning('Provider: ' . get_class($provider) .' does not support account migration.');
155 throw new InvalidArgumentException('Invalid auth provider given.');
156 }
157 $provider->createNewAccount($this->getStatus());
158
159 switch($this->getStatus()->getStatus())
160 {
162 return $this->handleAuthenticationSuccess($provider);
163
164 }
165 }
166 return $this->handleAuthenticationFail();
167 }
168
169
170
174 public function authenticate()
175 {
176 foreach($this->getProviders() as $provider)
177 {
178 $this->resetStatus();
179
180 $this->getLogger()->debug('Trying authentication against: ' . get_class($provider));
181
182 $provider->doAuthentication($this->getStatus());
183
184 $this->getLogger()->debug('Authentication user id: ' . $this->getStatus()->getAuthenticatedUserId());
185
186 switch($this->getStatus()->getStatus())
187 {
189 return $this->handleAuthenticationSuccess($provider);
190
192 $this->getLogger()->notice("Account migration required.");
193 return $this->handleAccountMigration($provider);
194
196 default:
197 $this->getLogger()->debug('Authentication failed against: ' . get_class($provider));
198 break;
199 }
200 }
201 return $this->handleAuthenticationFail();
202 }
203
209 {
210 $this->getLogger()->debug('Trigger auth mode: ' . $provider->getTriggerAuthMode());
211 $this->getLogger()->debug('Desired auth mode: ' . $provider->getUserAuthModeName());
212 $this->getLogger()->debug('External account: ' . $provider->getExternalAccountName());
213
214 $this->getStatus()->setAuthenticatedUserId(ANONYMOUS_USER_ID);
215 #$this->getStatus()->setStatus(ilAuthStatus::STATUS_AUTHENTICATED);
216
217 ilSession::set(static::MIG_TRIGGER_AUTHMODE, $provider->getTriggerAuthMode());
218 ilSession::set(static::MIG_DESIRED_AUTHMODE, $provider->getUserAuthModeName());
219 ilSession::set(static::MIG_EXTERNAL_ACCOUNT, $provider->getExternalAccountName());
220
221 $this->getLogger()->dump($_SESSION, ilLogLevel::DEBUG);
222
223 return true;
224 }
225
231 {
232 include_once './Services/Object/classes/class.ilObjectFactory.php';
233 $factory = new ilObjectFactory();
234 $user = $factory->getInstanceByObjId($this->getStatus()->getAuthenticatedUserId(),false);
235
236 // reset expired status
237 $this->getAuthSession()->setExpired(false);
238
239 if(!$user instanceof ilObjUser)
240 {
241 $this->getLogger()->error('Cannot instatiate user account with id: ' . $this->getStatus()->getAuthenticatedUserId());
243 $this->getStatus()->setAuthenticatedUserId(0);
244 $this->getStatus()->setReason('auth_err_invalid_user_account');
245 return false;
246 }
247
248 if(!$this->checkExceededLoginAttempts($user))
249 {
250 $this->getLogger()->info('Authentication failed for inactive user with id and too may login attempts: ' . $this->getStatus()->getAuthenticatedUserId());
252 $this->getStatus()->setAuthenticatedUserId(0);
253 $this->getStatus()->setReason('err_inactive_login_attempts');
254 return false;
255 }
256
257 if(!$this->checkActivation($user))
258 {
259 $this->getLogger()->info('Authentication failed for inactive user with id: ' . $this->getStatus()->getAuthenticatedUserId());
261 $this->getStatus()->setAuthenticatedUserId(0);
262 $this->getStatus()->setReason('err_inactive');
263 return false;
264 }
265
266 // time limit
267 if(!$this->checkTimeLimit($user))
268 {
269 $this->getLogger()->info('Authentication failed (time limit restriction) for user with id: ' . $this->getStatus()->getAuthenticatedUserId());
270
271 if($GLOBALS['ilSetting']->get('user_reactivate_code'))
272 {
273 $this->getLogger()->debug('Accout reactivation codes are active');
275 }
276 else
277 {
278 $this->getLogger()->debug('Accout reactivation codes are inactive');
280 $this->getStatus()->setAuthenticatedUserId(0);
281 }
282 $this->getStatus()->setReason('time_limit_reached');
283 return false;
284 }
285
286 // ip check
287 if(!$this->checkIp($user))
288 {
289 $this->getLogger()->info('Authentication failed (wrong ip) for user with id: ' . $this->getStatus()->getAuthenticatedUserId());
291 $this->getStatus()->setAuthenticatedUserId(0);
292
293 $this->getStatus()->setTranslatedReason(
294 sprintf(
295 $GLOBALS['DIC']->language()->txt('wrong_ip_detected'),
296 $_SERVER['REMOTE_ADDR']
297 )
298 );
299 return false;
300 }
301
302 // check simultaneos logins
303 $this->getLogger()->debug('Check simutaneous login');
304 if(!$this->checkSimultaneousLogins($user))
305 {
306 $this->getLogger()->info('Authentication failed: simultaneous logins forbidden for user: ' . $this->getStatus()->getAuthenticatedUserId());
308 $this->getStatus()->setAuthenticatedUserId(0);
309 $this->getStatus()->setReason('simultaneous_login_detected');
310 return false;
311 }
312
313 // check if profile is complete
314 include_once "Services/User/classes/class.ilUserProfile.php";
316 {
317 ilLoggerFactory::getLogger('auth')->info('User profile is incomplete.');
318 $user->setProfileIncomplete(true);
319 $user->update();
320 }
321
322 // redirects in case of error (session pool limit reached)
323 ilSessionControl::handleLoginEvent($user->getLogin(), $this->getAuthSession());
324
325
326 // @todo move to event handling
327 include_once 'Services/Tracking/classes/class.ilOnlineTracking.php';
328 ilOnlineTracking::addUser($user->getId());
329
330 // @todo move to event handling
331 include_once 'Modules/Forum/classes/class.ilObjForum.php';
332 ilObjForum::_updateOldAccess($user->getId());
333
334 require_once 'Services/PrivacySecurity/classes/class.ilSecuritySettings.php';
335 $security_settings = ilSecuritySettings::_getInstance();
336
337 // determine first login of user for setting an indicator
338 // which still is available in PersonalDesktop, Repository, ...
339 // (last login date is set to current date in next step)
340 if(
341 $security_settings->isPasswordChangeOnFirstLoginEnabled() &&
342 $user->getLastLogin() == null
343 )
344 {
345 $user->resetLastPasswordChange();
346 }
347 $user->refreshLogin();
348
349 // reset counter for failed logins
350 ilObjUser::_resetLoginAttempts($user->getId());
351
352
353 $this->getLogger()->info('Successfully authenticated: ' . ilObjUser::_lookupLogin($this->getStatus()->getAuthenticatedUserId()));
354 $this->getAuthSession()->setAuthenticated(true, $this->getStatus()->getAuthenticatedUserId());
355
356 include_once './Services/Init/classes/class.ilInitialisation.php';
357 ilInitialisation::initUserAccount();
358
359 ilSession::set('orig_request_target', '');
360 $user->hasToAcceptTermsOfServiceInSession(true);
361
362
363 // --- anonymous/registered user
364 $this->getLogger()->info(
365 'logged in as '. $user->getLogin() .
366 ', remote:' . $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'] .
367 ', server:' . $_SERVER['SERVER_ADDR'] . ':' . $_SERVER['SERVER_PORT']
368 );
369
370 // finally raise event
371 global $ilAppEventHandler;
372 $ilAppEventHandler->raise(
373 'Services/Authentication',
374 'afterLogin',
375 array(
376 'username' => $user->getLogin())
377 );
378
379 return true;
380
381 }
382
387 protected function checkActivation(ilObjUser $user)
388 {
389 return $user->getActive();
390 }
391
396 protected function checkExceededLoginAttempts(\ilObjUser $user)
397 {
398 if(in_array($user->getId(), array(ANONYMOUS_USER_ID)))
399 {
400 return true;
401 }
402
403 $isInactive = !$user->getActive();
404 if(!$isInactive)
405 {
406 return true;
407 }
408
409 require_once 'Services/PrivacySecurity/classes/class.ilSecuritySettings.php';
411 $maxLoginAttempts = $security->getLoginMaxAttempts();
412
413 if(!(int)$maxLoginAttempts)
414 {
415 return true;
416 }
417
418 $numLoginAttempts = \ilObjUser::_getLoginAttempts($user->getId());
419
420 return $numLoginAttempts < $maxLoginAttempts;
421 }
422
428 protected function checkTimeLimit(ilObjUser $user)
429 {
430 return $user->checkTimeLimit();
431 }
432
436 protected function checkIp(ilObjUser $user)
437 {
438 $clientip = $user->getClientIP();
439 if (trim($clientip) != "")
440 {
441 $clientip = preg_replace("/[^0-9.?*,:]+/","",$clientip);
442 $clientip = str_replace(".","\\.",$clientip);
443 $clientip = str_replace(Array("?","*",","), Array("[0-9]","[0-9]*","|"), $clientip);
444
445 ilLoggerFactory::getLogger('auth')->debug('Check ip ' . $clientip . ' against ' . $_SERVER['REMOTE_ADDR']);
446
447 if (!preg_match("/^".$clientip."$/", $_SERVER["REMOTE_ADDR"]))
448 {
449 return false;
450 }
451 }
452 return true;
453 }
454
459 protected function checkSimultaneousLogins(ilObjUser $user)
460 {
461 $this->getLogger()->debug('Setting prevent simultaneous session is: ' . (string) $GLOBALS['ilSetting']->get('ps_prevent_simultaneous_logins'));
462 if(
463 $GLOBALS['ilSetting']->get('ps_prevent_simultaneous_logins') &&
464 ilObjUser::hasActiveSession($user->getId(), $this->getAuthSession()->getId())
465 )
466 {
467 return false;
468 }
469 return true;
470 }
471
475 protected function handleAuthenticationFail()
476 {
477 $this->getLogger()->debug('Authentication failed for all authentication methods.');
478
479 $user_id = ilObjUser::_lookupId($this->getCredentials()->getUsername());
480 if(!in_array($user_id, array(ANONYMOUS_USER_ID)))
481 {
483 $login_attempts = ilObjUser::_getLoginAttempts($user_id);
484
485 $this->getLogger()->notice('Increased login attempts for user: ' . $this->getCredentials()->getUsername());
486
487 include_once './Services/PrivacySecurity/classes/class.ilSecuritySettings.php';
489 $max_attempts = $security->getLoginMaxAttempts();
490
491 if((int) $max_attempts && $login_attempts >= $max_attempts)
492 {
493 $this->getStatus()->setReason('auth_err_login_attempts_deactivation');
494 $this->getLogger()->warning('User account set to inactive due to exceeded login attempts.');
496 }
497 }
498 }
499
500}
501?>
sprintf('%.4f', $callTime)
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
Description of class class.
resetStatus()
Reset status.
getLogger()
Get logger.
checkActivation(ilObjUser $user)
Check activation.
checkIp(ilObjUser $user)
Check ip.
handleAuthenticationFail()
Handle failed authenication.
authenticate()
Try to authenticate user.
checkExceededLoginAttempts(\ilObjUser $user)
checkTimeLimit(ilObjUser $user)
Check time limit.
handleAccountMigration(ilAuthProviderAccountMigrationInterface $provider)
Handle account migration.
migrateAccountNew()
Create new user account.
__construct(ilAuthSession $session, ilAuthStatus $status, ilAuthCredentials $credentials, array $providers)
Constructor.
checkSimultaneousLogins(ilObjUser $user)
Check simultaneous logins.
migrateAccount(ilAuthSession $session)
Migrate Account to existing user account.
getAuthSession()
Get auth session.
getCredentials()
Get auth credentials.
getProviders()
Get providers.
handleAuthenticationSuccess(ilAuthProviderInterface $provider)
Handle successful authentication.
getUserId()
Get authenticated user id.
isAuthenticated()
Check if session is authenticated.
Auth status implementation.
const STATUS_CODE_ACTIVATION_REQUIRED
const STATUS_AUTHENTICATION_FAILED
const STATUS_ACCOUNT_MIGRATION_REQUIRED
static getLogger($a_component_id)
Get component logger.
static _resetLoginAttempts($a_usr_id)
getActive()
get user active state @access public
static _lookupLogin($a_user_id)
lookup login
static _incrementLoginAttempts($a_usr_id)
static _lookupId($a_user_str)
Lookup id by login.
static _setUserInactive($a_usr_id)
static _getLoginAttempts($a_usr_id)
static hasActiveSession($a_user_id, $a_session_id)
Check for simultaneous login.
getClientIP()
get client ip number @access public
Class ilObjectFactory.
getId()
get object id @access public
static _getInstance()
Get instance of ilSecuritySettings.
static handleLoginEvent($a_login, ilAuthSession $auth_session)
when current session is allowed to be created it marks it with type regarding to the sessions user co...
static set($a_var, $a_val)
Set a value.
static get($a_var)
Get a value.
static isProfileIncomplete($a_user, $a_include_udf=true, $a_personal_data_only=true)
Check if all required personal data fields are set.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
Interface of auth credentials.
getExternalAccountName()
Get external account name.
getTriggerAuthMode()
Get auth mode which triggered the account migration 2_1 for ldap account migration with server id 1 1...
getUserAuthModeName()
Get user auth mode name ldap_1 for ldap account migration with server id 1 apache for apache auth.
Standard interface for auth provider implementations.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']