/** * @return string * @throws \TYPO3\Flow\Security\Exception\InvalidArgumentForHashGenerationException */ public function getJWTToken() { /** @var \TYPO3\Flow\Security\Account $account */ $account = $this->securityContext->getAccount(); $this->apiToken = $this->securityContext->getAuthenticationTokensOfType('RFY\\JWT\\Security\\Authentication\\Token\\JwtToken')[0]; if ($account->getAuthenticationProviderName() !== $this->apiToken->getAuthenticationProviderName()) { // TODO: Currently you can get only 1 tokenAccount because of the duplication restraint based on accountIdentifier & AuthenticationProviderName $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($account->getAccountIdentifier(), $this->apiToken->getAuthenticationProviderName()); if ($account === NULL) { $account = $this->generateTokenAccount(); } } $payload = array(); $payload['identifier'] = $account->getAccountIdentifier(); $payload['partyIdentifier'] = $this->persistenceManager->getIdentifierByObject($account->getParty()); $payload['user_agent'] = $this->request->getHeader('User-Agent'); $payload['ip_address'] = $this->request->getClientIpAddress(); if ($account->getCreationDate() instanceof \DateTime) { $payload['creationDate'] = $account->getCreationDate()->getTimestamp(); } if ($account->getExpirationDate() instanceof \DateTime) { $payload['expirationDate'] = $account->getExpirationDate()->getTimestamp(); } // Add hmac $hmac = $this->hashService->generateHmac($this->signature); return JWT::encode($payload, $hmac); }
/** * Sets isAuthenticated to TRUE for all tokens. * * @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 Typo3OrgSsoToken) { 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; $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, &$account) { $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName); }); } if (is_object($account)) { $authenticationData = 'version=' . $credentials['version'] . '&user='******'username'] . '&tpa_id=' . $credentials['tpaId'] . '&expires=' . $credentials['expires'] . '&action=' . $credentials['action'] . '&flags=' . $credentials['flags'] . '&userdata=' . $credentials['userdata']; if ($this->rsaWalletService->verifySignature($authenticationData, $credentials['signature'], $this->options['rsaKeyUuid']) && $credentials['expires'] > time()) { $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); } }
/** * Retrieves an existing user by the given username * * @param string $username The username * @return User The user, or NULL if the user does not exist */ public function getUser($username) { $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($username, self::ACCOUNT_AUTHENTICATION_PROVIDER); if ($account === NULL) { return NULL; } return $this->userRepository->findOneHavingAccount($account); }
/** * Action for creating a temporary account * * @param Registration $registration * @return void */ public function createAccountAction(Registration $registration) { $accountIdentifier = $registration->getUsername(); $existingAccount = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($accountIdentifier, 'Typo3BackendProvider'); if ($existingAccount !== NULL) { $this->addFlashMessage('An account with the username "%s" already exists.', 'Account already exists', Message::SEVERITY_ERROR, array($accountIdentifier)); $this->forward('newAccount'); } $this->createTemporaryAccount($accountIdentifier, $registration->getPassword(), $registration->getFirstName(), $registration->getLastName()); $uriBuilder = new UriBuilder(); $uriBuilder->setRequest($this->request->getParentRequest()); $redirectUri = $uriBuilder->setCreateAbsoluteUri(TRUE)->uriFor('index', array('username' => $accountIdentifier), 'Login', 'TYPO3.Neos'); $this->redirectToUri($redirectUri); }
/** * @param string $emailAddress * @param string $requirement * * @throws \Exception * * @return string */ public function resetPasswordAction($emailAddress, $requirement = '') { if ($requirement !== '') { throw new \Exception('Bot detection', 12393182738); } $locale = new Locale('nl'); $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($emailAddress, 'DefaultProvider'); if ($account instanceof Account) { try { /** @var Person $profile */ $profile = $this->profileService->getProfileNodeOfAccount($account); $password = $this->randomPassword(); $hashedPassword = $this->hashService->hashPassword($password, 'default'); $this->mailerService->sendEmail(array('email' => $emailAddress, 'name' => $profile->getDisplayName()), 'Nieuw wachtwoord', 'Packages/Application/BuJitsuDo.Authentication/Resources/Private/Templates/Email/PasswordReset.html', array('password' => $password, 'profile' => $profile)); $account->setCredentialsSource($hashedPassword); $this->accountRepository->update($account); $this->persistenceManager->persistAll(); } catch (\Exception $exception) { return $exception->getMessage(); } } else { $this->response->setHeader('Notification', $this->translator->translateById('profile.reset.password.response.failure', [], NULL, $locale, 'Main', 'BuJitsuDo.Authentication')); $this->response->setHeader('NotificationType', 'alert'); return ''; } $this->response->setHeader('Notification', $this->translator->translateById('profile.reset.password.response.success', [], NULL, $locale, 'Main', 'BuJitsuDo.Authentication')); $this->response->setHeader('NotificationType', 'success'); return ''; }
/** * @test */ public function authenticationWithCorrectCredentialsResetsFailedAuthenticationCount() { $this->authenticationToken->_set('credentials', ['username' => 'username', 'password' => 'wrongPW']); $this->persistedUsernamePasswordProvider->authenticate($this->authenticationToken); $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName('username', 'myTestProvider'); $this->assertEquals(1, $account->getFailedAuthenticationCount()); $this->authenticationToken->_set('credentials', ['username' => 'username', 'password' => 'password']); $this->persistedUsernamePasswordProvider->authenticate($this->authenticationToken); $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName('username', 'myTestProvider'); $this->assertEquals(new \DateTime(), $account->getLastSuccessfulAuthenticationDate()); $this->assertEquals(0, $account->getFailedAuthenticationCount()); }
/** * @param ResetPasswordFlow $resetPasswordFlow */ public function updatePasswordAction(ResetPasswordFlow $resetPasswordFlow) { $account = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($resetPasswordFlow->getEmail(), 'Sandstorm.UserManagement:Login'); if (!$account) { $this->view->assign('accountNotFound', true); return; } $this->view->assign('success', true); $account->setCredentialsSource($resetPasswordFlow->getEncryptedPassword()); $this->accountRepository->update($account); $this->resetPasswordFlowRepository->remove($resetPasswordFlow); }
/** * Persists new accounts only. If account is allready persisted, then account will be overridden with account from repository. * * @param string $providerName Provider name * @param Account $account account to persist. * * @return void */ private function persistAccount($providerName, Account &$account) { $accountFromRepository = $this->accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($account->getAccountIdentifier(), $account->getAuthenticationProviderName()); if ($accountFromRepository instanceof Account) { $account = $accountFromRepository; $this->updateRolesInAccount($providerName, $account); return; } $casAttributes = $this->casManager->getCasAttributes($providerName); $account->setRoles($this->getRoles($providerName, $casAttributes)); $this->mekeRedirectByNewUserIfNeeded($providerName, $account); $this->finalizePersistingNewUser($account); }
/** * 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; }