Example #1
0
 /**
  * @test
  * @dataProvider usernameSsoProvider
  */
 public function validateUserSupportsSSO($filter, $username, $expected)
 {
     $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ig_ldap_sso_auth'] = serialize(array('enableFESSO' => 1));
     \Causal\IgLdapSsoAuth\Library\Configuration::initialize('fe', new \Causal\IgLdapSsoAuth\Domain\Model\Configuration());
     $result = $this->fixture->validateUser($username, NULL, 'cn=read-only-admin,dc=example,dc=com', $filter);
     $this->assertEquals($expected, $result);
 }
Example #2
0
 /**
  * Default constructor.
  *
  * @param \Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration
  * @param string $context
  */
 public function __construct(\Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration, $context)
 {
     // Load the configuration
     Configuration::initialize($context, $configuration);
     // Store current context and get related configuration
     $this->context = $context;
     $this->configuration = strtolower($context) === 'fe' ? Configuration::getFrontendConfiguration() : Configuration::getBackendConfiguration();
     // Define related tables
     if ($context === 'be') {
         $this->userTable = 'be_users';
         $this->groupTable = 'be_groups';
     } else {
         $this->userTable = 'fe_users';
         $this->groupTable = 'fe_groups';
     }
 }
 /**
  * Find a user (eg. look up the user record in database when a login is sent)
  *
  * @return mixed user array or FALSE
  * @throws UnsupportedLoginSecurityLevelException
  */
 public function getUser()
 {
     $user = FALSE;
     $userRecordOrIsValid = FALSE;
     $enableFrontendSso = TYPO3_MODE === 'FE' && (bool) $this->config['enableFESSO'] && !empty($_SERVER['REMOTE_USER']);
     // This simple check is the key to prevent your log being filled up with warnings
     // due to the AJAX calls to maintain the session active if your configuration forces
     // the authentication stack to always fetch the user:
     // $TYPO3_CONF_VARS['SVCONF']['auth']['setup']['BE_alwaysFetchUser'] = true;
     // This is the case, e.g., when using EXT:crawler.
     if ($this->login['status'] !== 'login' && !$enableFrontendSso) {
         return $user;
     }
     /** @var \Causal\IgLdapSsoAuth\Domain\Repository\ConfigurationRepository $configurationRepository */
     $configurationRepository = GeneralUtility::makeInstance('Causal\\IgLdapSsoAuth\\Domain\\Repository\\ConfigurationRepository');
     $configurationRecords = $configurationRepository->findAll();
     if (count($configurationRecords) === 0) {
         // Early return since LDAP is not configured
         static::getLogger()->warning('Skipping LDAP authentication as extension is not yet configured');
         $this->cleanUpExtbaseDataMapper();
         return FALSE;
     }
     foreach ($configurationRecords as $configurationRecord) {
         Configuration::initialize(TYPO3_MODE, $configurationRecord);
         if (!Configuration::isEnabledForCurrentHost()) {
             $msg = sprintf('Configuration record #%s is not enabled for domain %s', $configurationRecord->getUid(), GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'));
             static::getLogger()->info($msg);
             continue;
         }
         // Enable feature
         $userRecordOrIsValid = FALSE;
         // Single Sign-On authentication
         if ($enableFrontendSso) {
             $remoteUser = $_SERVER['REMOTE_USER'];
             // Strip the domain name
             if ($pos = strpos($remoteUser, '@')) {
                 $remoteUser = substr($remoteUser, 0, $pos);
             } elseif ($pos = strrpos($remoteUser, '\\')) {
                 $remoteUser = substr($remoteUser, $pos + 1);
             }
             $userRecordOrIsValid = Authentication::ldapAuthenticate($remoteUser);
             if (is_array($userRecordOrIsValid)) {
                 // Useful for debugging purpose
                 $this->login['uname'] = $remoteUser;
             }
             // Authenticate user from LDAP
         } elseif ($this->login['status'] === 'login' && $this->login['uident']) {
             // Configuration of authentication service.
             $loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['loginSecurityLevel'];
             // normal case
             // Check if $loginSecurityLevel is set to "challenged" or "superchallenged" and throw an error if the configuration allows it
             // By default, it will not throw an exception
             if (isset($this->config['throwExceptionAtLogin']) && $this->config['throwExceptionAtLogin'] == 1) {
                 if ($loginSecurityLevel === 'challenged' || $loginSecurityLevel === 'superchallenged') {
                     $message = "ig_ldap_sso_auth error: current login security level '" . $loginSecurityLevel . "' is not supported.";
                     $message .= " Try to use 'normal' or 'rsa' (highly recommended): ";
                     $message .= "\$GLOBALS['TYPO3_CONF_VARS']['" . TYPO3_MODE . "']['loginSecurityLevel'] = 'rsa';";
                     $this->cleanUpExtbaseDataMapper();
                     throw new UnsupportedLoginSecurityLevelException($message, 1324313489);
                 }
             }
             // normal case
             $password = $this->login['uident_text'];
             try {
                 if ($password !== NULL) {
                     $userRecordOrIsValid = Authentication::ldapAuthenticate($this->login['uname'], $password);
                 } else {
                     // Could not decrypt password
                     $userRecordOrIsValid = FALSE;
                 }
             } catch (UnresolvedPhpDependencyException $e) {
                 // Possible known exception: 1409566275, LDAP extension is not available for PHP
                 $userRecordOrIsValid = FALSE;
             }
         }
         if (is_array($userRecordOrIsValid)) {
             $user = $userRecordOrIsValid;
             break;
         } elseif ($userRecordOrIsValid) {
             // Authentication is valid
             break;
         } else {
             $diagnostic = Authentication::getLastAuthenticationDiagnostic();
             $info = array('username' => $this->login['uname'], 'remote' => sprintf('%s (%s)', $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST']), 'diagnostic' => $diagnostic, 'configUid' => $configurationRecord->getUid());
             static::getLogger()->error('Authentication failed', $info);
             NotificationUtility::dispatch(__CLASS__, 'authenticationFailed', $info);
         }
         // Continue and try with next configuration record...
     }
     if (!$user && $userRecordOrIsValid) {
         $user = $this->fetchUserRecord($this->login['uname']);
     }
     if (is_array($user)) {
         static::getLogger()->debug(sprintf('User found: "%s"', $this->login['uname']));
     }
     $this->cleanUpExtbaseDataMapper();
     return $user;
 }
Example #4
0
 /**
  * Actual import of user groups using AJAX.
  *
  * @param \Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration
  * @param string $mode
  * @param string $dn
  * @return void
  */
 public function importUserGroupsAjaxAction(\Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration = NULL, $mode, $dn)
 {
     $data = array();
     Configuration::initialize($mode, $configuration);
     $config = $mode === 'be' ? Configuration::getBackendConfiguration() : Configuration::getFrontendConfiguration();
     try {
         $success = $this->ldap->connect(Configuration::getLdapConfiguration());
     } catch (\Exception $e) {
         $data['message'] = $e->getMessage();
         $success = FALSE;
     }
     if ($success) {
         list($filter, $baseDn) = explode(',', $dn, 2);
         $ldapGroup = $this->ldap->search($baseDn, '(' . $filter . ')', array(), TRUE);
         $pid = Configuration::getPid($config['groups']['mapping']);
         $table = $mode === 'be' ? 'be_groups' : 'fe_groups';
         $typo3Groups = Authentication::getTypo3Groups(array($ldapGroup), $table, $pid);
         // Merge LDAP and TYPO3 information
         $group = Authentication::merge($ldapGroup, $typo3Groups[0], $config['groups']['mapping']);
         if ((int) $group['uid'] === 0) {
             $group = Typo3GroupRepository::add($table, $group);
         } else {
             // Restore group that may have been previously deleted
             $group['deleted'] = 0;
             $success = Typo3GroupRepository::update($table, $group);
         }
         if (!empty($config['groups']['mapping']['parentGroup'])) {
             $fieldParent = $config['groups']['mapping']['parentGroup'];
             if (preg_match("`<([^\$]*)>`", $fieldParent, $attribute)) {
                 $fieldParent = $attribute[1];
                 if (is_array($group[$fieldParent])) {
                     unset($group[$fieldParent]['count']);
                     $this->setParentGroup($group[$fieldParent], $fieldParent, $group['uid'], $pid, $mode);
                 }
             }
         }
         $data['id'] = (int) $group['uid'];
     }
     $this->returnAjax(array_merge($data, array('success' => $success)));
 }