/**
  * @param TokenInterface $authenticationToken
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof Typo3OrgSsoToken) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339840);
     }
     /** @var $account Account */
     $account = null;
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['username'])) {
         $providerName = $this->name;
         $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, &$account) {
             $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName);
         });
     }
     $authenticationData = 'version=' . $credentials['version'] . '&user='******'username'] . '&tpa_id=' . $credentials['tpaId'] . '&expires=' . $credentials['expires'] . '&action=' . $credentials['action'] . '&flags=' . $credentials['flags'] . '&userdata=' . $credentials['userdata'];
     $authenticationDataIsValid = $this->rsaWalletService->verifySignature($authenticationData, $credentials['signature'], $this->options['rsaKeyUuid']);
     if ($authenticationDataIsValid && $credentials['expires'] > time()) {
         $userdata = $this->parseUserdata($credentials['userdata']);
         if (!is_object($account)) {
             $account = $this->createAccount($userdata);
         } elseif (is_object($account)) {
             $account = $this->updateAccount($account, $userdata);
         }
         $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
         $authenticationToken->setAccount($account);
     } else {
         $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
     }
 }
 /**
  * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded.
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @Flow\Session(autoStart=true)
  */
 public function authenticate(\TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof SingleSignOnToken) {
         throw new \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1351008039);
     }
     if ($authenticationToken->getAuthenticationStatus() === \TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_NEEDED) {
         // Verify signature with server public key
         $credentials = $authenticationToken->getCredentials();
         $signature = $credentials['signature'];
         $accessTokenCipher = $credentials['accessToken'];
         $ssoServer = $this->createSsoServer();
         if (!$ssoServer->verifyCallbackSignature($accessTokenCipher, $signature)) {
             throw new Exception('Could not verify signature of access token', 1351008742);
         }
         $ssoClient = $this->ssoClientFactory->create();
         $accessToken = $ssoClient->decryptCallbackAccessToken($accessTokenCipher);
         if ($accessToken === '') {
             throw new Exception('Could not decrypt access token', 1351690950);
         }
         $authenticationData = $ssoServer->redeemAccessToken($ssoClient, $accessToken);
         // TODO Check validity of authentication data (presence of "account" and "sessionId")
         $account = $this->globalAccountMapper->getAccount($ssoClient, $authenticationData['account']);
         $globalSessionId = $authenticationData['sessionId'];
         $this->session->addTag('Flowpack_SingleSignOn_Client-' . $globalSessionId);
         $authenticationToken->setGlobalSessionId($globalSessionId);
         $authenticationToken->setAccount($account);
         $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL);
     } elseif ($authenticationToken->getAuthenticationStatus() !== \TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * Checks the given token for validity and sets the token authentication status
  * accordingly (success, wrong credentials or no credentials given).
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof UsernamePassword) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339840);
     }
     /** @var $account \TYPO3\Flow\Security\Account */
     $account = null;
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['username'])) {
         $providerName = $this->name;
         $accountRepository = $this->accountRepository;
         $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, $accountRepository, &$account) {
             $account = $accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName);
         });
     }
     if (is_object($account)) {
         if ($this->hashService->validatePassword($credentials['password'], $account->getCredentialsSource())) {
             $account->authenticationAttempted(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $authenticationToken->setAccount($account);
         } else {
             $account->authenticationAttempted(TokenInterface::WRONG_CREDENTIALS);
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         }
         $this->accountRepository->update($account);
         $this->persistenceManager->whitelistObject($account);
     } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * Authenticates against a crowd instance.
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof UsernamePassword) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339845);
     }
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['username']) && isset($credentials['password'])) {
         $crowdAuthenticationResponse = $this->crowdClient->authenticate($credentials['username'], $credentials['password']);
         if ($crowdAuthenticationResponse !== NULL) {
             /** @var $account \TYPO3\Flow\Security\Account */
             $account = NULL;
             $providerName = $this->name;
             $accountRepository = $this->accountRepository;
             $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, $accountRepository, &$account) {
                 $account = $accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName);
             });
             if ($account === NULL) {
                 $account = new Account();
                 $account->setAuthenticationProviderName($providerName);
                 $account->setAccountIdentifier($credentials['username']);
                 $this->accountRepository->add($account);
             }
             $authenticateRole = $this->policyService->getRole($this->options['authenticateRole']);
             if ($account->hasRole($authenticateRole) === FALSE) {
                 $account->addRole($authenticateRole);
             }
             $crowdUser = $this->partyService->getAssignedPartyOfAccount($account);
             if ($crowdUser instanceof Person) {
                 if ($crowdUser->getName()->getFirstName() !== $crowdAuthenticationResponse['first-name']) {
                     $crowdUser->getName()->setFirstName($crowdAuthenticationResponse['first-name']);
                     $this->partyRepository->update($crowdUser);
                 }
                 if ($crowdUser->getName()->getLastName() !== $crowdAuthenticationResponse['last-name']) {
                     $crowdUser->getName()->setLastName($crowdAuthenticationResponse['last-name']);
                     $this->partyRepository->update($crowdUser);
                 }
                 if ($crowdUser->getPrimaryElectronicAddress()->getIdentifier() !== $crowdAuthenticationResponse['email']) {
                     $crowdUser->getPrimaryElectronicAddress()->setIdentifier($crowdAuthenticationResponse['email']);
                     $this->partyRepository->update($crowdUser);
                 }
             } else {
                 $crowdUser = new Person();
                 $crowdUser->setName(new PersonName('', $crowdAuthenticationResponse['first-name'], '', $crowdAuthenticationResponse['last-name']));
                 $email = new ElectronicAddress();
                 $email->setIdentifier($crowdAuthenticationResponse['email']);
                 $email->setType(ElectronicAddress::TYPE_EMAIL);
                 $crowdUser->setPrimaryElectronicAddress($email);
                 $this->partyRepository->add($crowdUser);
                 $this->partyService->assignAccountToParty($account, $crowdUser);
             }
             $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $authenticationToken->setAccount($account);
         } else {
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         }
     } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * Returns TRUE if the given token can be authenticated by this provider
  *
  * @param TokenInterface $authenticationToken The token that should be authenticated
  * @return boolean TRUE if the given token class can be authenticated by this provider
  */
 public function canAuthenticate(TokenInterface $authenticationToken)
 {
     if ($authenticationToken->getAuthenticationProviderName() === $this->name) {
         return true;
     } else {
         return false;
     }
 }
 /**
  * Returns TRUE if the given token can be authenticated by this provider
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token that should be authenticated
  * @return boolean TRUE if the given token class can be authenticated by this provider
  */
 public function canAuthenticate(\TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken)
 {
     if ($authenticationToken->getAuthenticationProviderName() === $this->name) {
         return TRUE;
     } else {
         return FALSE;
     }
 }
 /**
  * Sets isAuthenticated to TRUE for all tokens.
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @return void
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     $authenticationToken->setAuthenticationStatus($this->authenticationStatus);
     if ($this->authenticationStatus === TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAccount($this->account);
     } else {
         $authenticationToken->setAccount(null);
     }
 }
 /**
  * Sets isAuthenticated to TRUE for all tokens.
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @return void
  */
 public function authenticate(\TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken)
 {
     $authenticationToken->setAuthenticationStatus($this->authenticationStatus);
     if ($this->authenticationStatus === \TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAccount($this->account);
     } else {
         $authenticationToken->setAccount(NULL);
     }
 }
 /**
  * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded.
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  * @return void
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof AbstractClientToken) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1383754993);
     }
     $credentials = $authenticationToken->getCredentials();
     // There is no way to validate the Token or check the scopes at the moment apart from "trying" (and possibly receiving an access denied)
     // we could check the validity of the Token and the scopes here in the future when Instagram provides that
     // Only check if an access Token is present at this time and do a single test call
     if (isset($credentials['accessToken']) && $credentials['accessToken'] !== NULL) {
         // check if a secure request is possible (https://www.instagram.com/developer/secure-api-requests/)
         $userInfo = $this->instagramTokenEndpoint->validateSecureRequestCapability($credentials['accessToken']);
         if ($userInfo === FALSE) {
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
             $this->securityLogger->log('A secure call to the API with the provided accessToken and clientSecret was not possible', LOG_NOTICE);
             return FALSE;
         }
     } else {
     }
     // From here, we surely know the user is considered authenticated against the remote service,
     // yet to check if there is an immanent account present.
     $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
     /** @var $account \TYPO3\Flow\Security\Account */
     $account = NULL;
     $providerName = $this->name;
     $accountRepository = $this->accountRepository;
     $this->securityContext->withoutAuthorizationChecks(function () use($userInfo, $providerName, $accountRepository, &$account) {
         $account = $accountRepository->findByAccountIdentifierAndAuthenticationProviderName($userInfo['id'], $providerName);
     });
     if ($account === NULL) {
         $account = new Account();
         $account->setAccountIdentifier($userInfo['id']);
         $account->setAuthenticationProviderName($providerName);
         $this->accountRepository->add($account);
     }
     $authenticationToken->setAccount($account);
     // the access token is valid for an "undefined time" according to instagram (so we cannot know when the user needs to log in again)
     $account->setCredentialsSource($credentials['accessToken']);
     $this->accountRepository->update($account);
     // check if a user is already attached to this account
     if ($this->partyService->getAssignedPartyOfAccount($account) === null || count($this->partyService->getAssignedPartyOfAccount($account)) < 1) {
         $user = $this->userService->getCurrentUser();
         if ($user !== null) {
             $user->addAccount($account);
             $this->userService->updateUser($user);
             $this->persistenceManager->whitelistObject($user);
         } else {
             $this->securityLogger->logException(new Exception("The InstagramProvider was unable to determine the backend user, make sure the configuration Typo3BackendProvider requestPattern matches the Instagram Controller and the authentication strategy is set to 'atLeastOne' Token"));
         }
     }
     // persistAll is called automatically at the end of this function, account gets whitelisted to allow
     // persisting for an object thats tinkered with via a GET request
     $this->persistenceManager->whitelistObject($account);
 }
 /**
  * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded.
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  * @return void
  */
 public function authenticate(\TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof OpauthToken) {
         throw new \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1381598908);
     }
     $response = $this->opauth->getResponse();
     if ($response !== NULL && $response->isAuthenticationSucceeded()) {
         $accountIdentifier = $this->accountService->createAccountIdentifier($response);
         $authenticationProviderName = $this->name;
         $account = $this->accountRepository->findByAccountIdentifierAndAuthenticationProviderName($accountIdentifier, $authenticationProviderName);
         if ($account !== NULL) {
             $authenticationToken->setAccount($account);
             $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL);
         }
     } else {
         $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded.
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  * @return void
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof AbstractClientToken) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1383754993);
     }
     $credentials = $authenticationToken->getCredentials();
     // Inspect the received access token as documented in https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/
     $tokenInformation = $this->facebookTokenEndpoint->requestValidatedTokenInformation($credentials['accessToken']);
     if ($tokenInformation === FALSE) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         return;
     }
     // Check if the permitted scopes suffice:
     $necessaryScopes = $this->options['scopes'];
     $scopesHavingPermissionFor = $tokenInformation['scopes'];
     $requiredButNotPermittedScopes = array_diff($necessaryScopes, $scopesHavingPermissionFor);
     if (count($requiredButNotPermittedScopes) > 0) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         $this->securityLogger->log('The permitted scopes do not satisfy the required once.', LOG_NOTICE, array('necessaryScopes' => $necessaryScopes, 'allowedScopes' => $scopesHavingPermissionFor));
         return;
     }
     // From here, we surely know the user is considered authenticated against the remote service,
     // yet to check if there is an immanent account present.
     $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
     /** @var $account \TYPO3\Flow\Security\Account */
     $account = NULL;
     $providerName = $this->name;
     $accountRepository = $this->accountRepository;
     $this->securityContext->withoutAuthorizationChecks(function () use($tokenInformation, $providerName, $accountRepository, &$account) {
         $account = $accountRepository->findByAccountIdentifierAndAuthenticationProviderName($tokenInformation['user_id'], $providerName);
     });
     if ($account === NULL) {
         $account = new Account();
         $account->setAccountIdentifier($tokenInformation['user_id']);
         $account->setAuthenticationProviderName($providerName);
         $this->accountRepository->add($account);
     }
     $authenticationToken->setAccount($account);
     // request long-live token and attach that to the account
     $longLivedToken = $this->facebookTokenEndpoint->requestLongLivedToken($credentials['accessToken']);
     $account->setCredentialsSource($longLivedToken);
     $this->accountRepository->update($account);
 }
 /**
  * Sets isAuthenticated to TRUE for all tokens.
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @throws UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof PasswordToken) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339840);
     }
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['password'])) {
         if ($this->hashService->validatePassword($credentials['password'], $this->fileBasedSimpleKeyService->getKey($this->options['keyName']))) {
             $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $account = new Account();
             $roles = array();
             foreach ($this->options['authenticateRoles'] as $roleIdentifier) {
                 $roles[] = $this->policyService->getRole($roleIdentifier);
             }
             $account->setRoles($roles);
             $authenticationToken->setAccount($account);
         } else {
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         }
     } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
示例#13
0
 /**
  * Checks the given token for validity and sets the token authentication status
  * accordingly (success, wrong credentials or no credentials given).
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @throws UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof JwtToken) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1417040168);
     }
     /** @var $account Account */
     $account = NULL;
     $credentials = $authenticationToken->getCredentials();
     if (!is_array($credentials) || !isset($credentials['token'])) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
         return;
     }
     $hmac = $this->hashService->generateHmac($this->signature);
     $payload = NULL;
     try {
         $payload = (array) JWT::decode($credentials['token'], $hmac, array('HS256'));
     } catch (\Exception $exception) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
     }
     if (isset($credentials['username'])) {
         $providerName = $this->name;
         $accountRepository = $this->accountRepository;
         $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, $accountRepository, &$account) {
             $account = $accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName);
         });
         if ($this->hashService->validatePassword($credentials['password'], $account->getCredentialsSource())) {
             $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $authenticationToken->setAccount($account);
             return;
         } else {
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
             return;
         }
     }
     if ($credentials['user_agent'] === $payload['user_agent'] && $credentials['ip_address'] === $payload['ip_address']) {
         $this->securityContext->withoutAuthorizationChecks(function () use($payload, &$account) {
             $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($payload['identifier'], $this->name);
         });
     }
     if (is_object($account)) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
         $authenticationToken->setAccount($account);
         return;
     }
     $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
     return;
 }
示例#14
0
 /**
  * Authenticate the current token. If it's not possible to connect to the LDAP server the provider
  * tries to authenticate against cached credentials in the database that were
  * cached on the last successful login for the user to authenticate.
  *
  * @param TokenInterface $authenticationToken The token to be authenticated
  * @throws UnsupportedAuthenticationTokenException
  * @return void
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof UsernamePassword) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339840);
     }
     $account = null;
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['username'])) {
         if ($this->directoryService->isServerOnline()) {
             try {
                 $ldapUser = $this->directoryService->authenticate($credentials['username'], $credentials['password']);
                 if ($ldapUser) {
                     $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $this->name);
                     $newlyCreatedAccount = false;
                     if ($account === null) {
                         $account = new Account();
                         $account->setAccountIdentifier($credentials['username']);
                         $account->setAuthenticationProviderName($this->name);
                         $this->createParty($account, $ldapUser);
                         $this->accountRepository->add($account);
                         $newlyCreatedAccount = true;
                     }
                     if ($account instanceof Account) {
                         if ($this->allowStandinAuthentication === true) {
                             // Cache the password to have cached login if LDAP is unavailable
                             $account->setCredentialsSource($this->hashService->generateHmac($credentials['password']));
                         }
                         $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
                         $authenticationToken->setAccount($account);
                         $this->setRoles($account, $ldapUser);
                         $this->emitRolesSet($account, $ldapUser);
                         if ($newlyCreatedAccount === false) {
                             $this->updateParty($account, $ldapUser);
                         }
                         $this->emitAccountAuthenticated($account, $ldapUser);
                         $this->accountRepository->update($account);
                     } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
                         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
                     }
                 } else {
                     $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
                 }
             } catch (\Exception $exception) {
                 $this->logger->log('Authentication failed: ' . $exception->getMessage(), LOG_ALERT);
             }
         } elseif ($this->allowStandinAuthentication === true) {
             $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $this->name);
             // Server not available, fallback to the cached password hash
             if ($account instanceof Account) {
                 if ($this->hashService->validateHmac($credentials['password'], $account->getCredentialsSource())) {
                     $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
                     $authenticationToken->setAccount($account);
                 } else {
                     $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
                 }
             } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
                 $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
             }
         } else {
             $this->logger->log('Authentication failed: directory server offline and standin authentication is disabled', LOG_ALERT);
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         }
     } else {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * Evaluates any RequestPatterns of the given token to determine whether it is active for the current request
  * - If no RequestPattern is configured for this token, it is active
  * - Otherwise it is active only if at least one configured RequestPattern per type matches the request
  *
  * @param TokenInterface $token
  * @return bool TRUE if the given token is active, otherwise FALSE
  */
 protected function isTokenActive(TokenInterface $token)
 {
     if (!$token->hasRequestPatterns()) {
         return true;
     }
     $requestPatternsByType = [];
     /** @var $requestPattern RequestPatternInterface */
     foreach ($token->getRequestPatterns() as $requestPattern) {
         $patternType = TypeHandling::getTypeForValue($requestPattern);
         if (isset($requestPatternsByType[$patternType]) && $requestPatternsByType[$patternType] === true) {
             continue;
         }
         $requestPatternsByType[$patternType] = $requestPattern->matchRequest($this->request);
     }
     return !in_array(false, $requestPatternsByType, true);
 }
 /**
  * @param TokenInterface $foreignAccountToken
  * @param AbstractClientToken $possibleOAuthTokenAuthenticatedWithoutParty
  */
 public function setPartyOfAuthenticatedTokenAndAttachToAccountFor(TokenInterface $foreignAccountToken, AbstractClientToken $possibleOAuthTokenAuthenticatedWithoutParty)
 {
     $oauthAccount = $possibleOAuthTokenAuthenticatedWithoutParty->getAccount();
     // TODO: this must be properly specifiable (the Roles to add)
     #$oauthAccount->setRoles();
     $oauthAccount->setParty($foreignAccountToken->getAccount()->getParty());
     $this->accountRepository->update($oauthAccount);
 }