Has to add a TokenInterface to the security context Might set a UserDetailsService, RequestPattern and AuthenticationEntryPoint (from configuration).
示例#1
0
 /**
  * @param integer $step
  * @return void
  * @Flow\SkipCsrfProtection
  */
 public function indexAction($step = 0)
 {
     $this->currentStepIndex = $step;
     $this->checkRequestedStepIndex();
     $currentStep = $this->instantiateCurrentStep();
     $controller = $this;
     $callback = function (\Neos\Form\Core\Model\FinisherContext $finisherContext) use($controller, $currentStep) {
         $controller->postProcessStep($finisherContext->getFormValues(), $currentStep);
     };
     $formDefinition = $currentStep->getFormDefinition($callback);
     if ($this->currentStepIndex > 0) {
         $formDefinition->setRenderingOption('previousStepUri', $this->uriBuilder->uriFor('index', ['step' => $this->currentStepIndex - 1]));
     }
     if ($currentStep->isOptional()) {
         $formDefinition->setRenderingOption('nextStepUri', $this->uriBuilder->uriFor('index', ['step' => $this->currentStepIndex + 1]));
     }
     $totalAmountOfSteps = count($this->settings['steps']);
     if ($this->currentStepIndex === $totalAmountOfSteps - 1) {
         $formDefinition->setRenderingOption('finalStep', true);
         $this->authenticationManager->logout();
     }
     $response = new \Neos\Flow\Http\Response($this->response);
     $form = $formDefinition->bind($this->request, $response);
     try {
         $renderedForm = $form->render();
     } catch (\Neos\Setup\Exception $exception) {
         $this->addFlashMessage($exception->getMessage(), 'Exception while executing setup step', \Neos\Error\Messages\Message::SEVERITY_ERROR);
         $this->redirect('index', null, null, ['step' => $this->currentStepIndex]);
     }
     $this->view->assignMultiple(['form' => $renderedForm, 'totalAmountOfSteps' => $totalAmountOfSteps, 'currentStepNumber' => $this->currentStepIndex + 1]);
 }
 /**
  * Sets up this test case
  */
 public function setUp()
 {
     $this->securityContext = $this->getAccessibleMock(Context::class, ['separateActiveAndInactiveTokens']);
     $this->mockAuthenticationManager = $this->createMock(AuthenticationManagerInterface::class);
     $this->mockAuthenticationManager->expects($this->any())->method('getTokens')->will($this->returnValue([]));
     $this->securityContext->injectAuthenticationManager($this->mockAuthenticationManager);
     $this->mockActionRequest = $this->getMockBuilder(ActionRequest::class)->disableOriginalConstructor()->getMock();
     $this->securityContext->setRequest($this->mockActionRequest);
 }
 /**
  * Matches a \Neos\Flow\Mvc\RequestInterface against the configured CSRF pattern rules and
  * searches for invalid csrf tokens. If this returns TRUE, the request is invalid!
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws AuthenticationRequiredException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest || $request->getHttpRequest()->isMethodSafe()) {
         $this->systemLogger->log('CSRF: No token required, safe request', LOG_DEBUG);
         return false;
     }
     if ($this->authenticationManager->isAuthenticated() === false) {
         $this->systemLogger->log('CSRF: No token required, not authenticated', LOG_DEBUG);
         return false;
     }
     if ($this->securityContext->areAuthorizationChecksDisabled() === true) {
         $this->systemLogger->log('CSRF: No token required, authorization checks are disabled', LOG_DEBUG);
         return false;
     }
     $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName());
     $actionMethodName = $request->getControllerActionName() . 'Action';
     if (!$this->hasPolicyEntryForMethod($controllerClassName, $actionMethodName)) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is not restricted by a policy.', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     if ($this->reflectionService->isMethodTaggedWith($controllerClassName, $actionMethodName, 'skipcsrfprotection')) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is tagged with a "skipcsrfprotection" annotation', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     $httpRequest = $request->getHttpRequest();
     if ($httpRequest->hasHeader('X-Flow-Csrftoken')) {
         $csrfToken = $httpRequest->getHeader('X-Flow-Csrftoken');
     } else {
         $internalArguments = $request->getMainRequest()->getInternalArguments();
         $csrfToken = isset($internalArguments['__csrfToken']) ? $internalArguments['__csrfToken'] : null;
     }
     if (empty($csrfToken)) {
         $this->systemLogger->log(sprintf('CSRF: token was empty but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     if (!$this->securityContext->hasCsrfProtectionTokens()) {
         throw new AuthenticationRequiredException(sprintf('CSRF: No CSRF tokens in security context, possible session timeout. A valid token is required for %s::%s()', $controllerClassName, $actionMethodName), 1317309673);
     }
     if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === false) {
         $this->systemLogger->log(sprintf('CSRF: token was invalid but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     $this->systemLogger->log(sprintf('CSRF: Successfully verified token for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
     return false;
 }
 /**
  * @test
  */
 public function csrfTokenFieldIsRenderedForUnsafeRequests()
 {
     /** @var FormViewHelper|\PHPUnit_Framework_MockObject_MockObject $viewHelper */
     $viewHelper = $this->getAccessibleMock(\Neos\FluidAdaptor\ViewHelpers\FormViewHelper::class, null, array(), '', false);
     $this->injectDependenciesIntoViewHelper($viewHelper);
     $this->securityContext->expects($this->any())->method('isInitialized')->will($this->returnValue(true));
     $this->mockAuthenticationManager->expects($this->any())->method('isAuthenticated')->will($this->returnValue(true));
     $this->securityContext->expects($this->atLeastOnce())->method('getCsrfProtectionToken')->will($this->returnValue('CSRFTOKEN'));
     $this->assertEquals('<input type="hidden" name="__csrfToken" value="CSRFTOKEN" />' . chr(10), $viewHelper->_call('renderCsrfTokenField'));
 }
 /**
  * Prepares the environment for and conducts an account authentication
  *
  * @param \Neos\Flow\Security\Account $account
  * @return void
  * @api
  */
 protected function authenticateAccount(\Neos\Flow\Security\Account $account)
 {
     $this->testingProvider->setAuthenticationStatus(\Neos\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL);
     $this->testingProvider->setAccount($account);
     $this->securityContext->clearContext();
     $requestHandler = self::$bootstrap->getActiveRequestHandler();
     $actionRequest = $this->route($requestHandler->getHttpRequest());
     $this->securityContext->setRequest($actionRequest);
     $this->authenticationManager->authenticate();
 }
 /**
  * Render the a hidden field with a CSRF token
  *
  * @return string the CSRF token field
  */
 protected function renderCsrfTokenField()
 {
     if (strtolower($this->arguments['method']) === 'get') {
         return '';
     }
     if (!$this->securityContext->isInitialized() || !$this->authenticationManager->isAuthenticated()) {
         return '';
     }
     $csrfToken = $this->securityContext->getCsrfProtectionToken();
     return '<input type="hidden" name="__csrfToken" value="' . htmlspecialchars($csrfToken) . '" />' . chr(10);
 }
 /**
  * Invokes the security interception
  *
  * @return boolean TRUE if the security checks was passed
  * @throws AccessDeniedException
  * @throws AuthenticationRequiredException if an entity could not be found (assuming it is bound to the current session), causing a redirect to the authentication entrypoint
  * @throws NoTokensAuthenticatedException if no tokens could be found and the accessDecisionManager denied access to the privilege target, causing a redirect to the authentication entrypoint
  */
 public function invoke()
 {
     $reason = '';
     $privilegeSubject = new MethodPrivilegeSubject($this->joinPoint);
     try {
         $this->authenticationManager->authenticate();
     } catch (EntityNotFoundException $exception) {
         throw new AuthenticationRequiredException('Could not authenticate. Looks like a broken session.', 1358971444, $exception);
     } catch (NoTokensAuthenticatedException $noTokensAuthenticatedException) {
         // We still need to check if the privilege is available to "Neos.Flow:Everybody".
         if ($this->privilegeManager->isGranted(MethodPrivilegeInterface::class, $privilegeSubject, $reason) === false) {
             throw new NoTokensAuthenticatedException($noTokensAuthenticatedException->getMessage() . chr(10) . $reason, $noTokensAuthenticatedException->getCode());
         }
     }
     if ($this->privilegeManager->isGranted(MethodPrivilegeInterface::class, $privilegeSubject, $reason) === false) {
         throw new AccessDeniedException($this->renderDecisionReasonMessage($reason), 1222268609);
     }
 }
 /**
  * Invokes the the authentication, if needed.
  *
  * @return boolean TRUE if the security checks was passed
  */
 public function invoke()
 {
     $this->authenticationManager->authenticate();
 }
 /**
  * Logs all active tokens out. Override this, if you want to
  * have some custom action here. You can always call the parent
  * method to do the actual logout.
  *
  * @return void
  */
 public function logoutAction()
 {
     $this->authenticationManager->logout();
 }
示例#10
0
 /**
  * Logout all active authentication tokens.
  *
  * @return void
  */
 public function logoutAction()
 {
     $this->authenticationManager->logout();
     $this->addFlashMessage('Successfully logged out.', 'Logged out');
     $this->redirect('login');
 }
 /**
  * Returns TRUE, if at least one of the currently authenticated accounts holds
  * a role with the given identifier, also recursively.
  *
  * @param string $roleIdentifier The string representation of the role to search for
  * @return boolean TRUE, if a role with the given string representation was found
  */
 public function hasRole($roleIdentifier)
 {
     if ($roleIdentifier === 'Neos.Flow:Everybody') {
         return true;
     }
     if ($roleIdentifier === 'Neos.Flow:Anonymous') {
         return !$this->authenticationManager->isAuthenticated();
     }
     if ($roleIdentifier === 'Neos.Flow:AuthenticatedUser') {
         return $this->authenticationManager->isAuthenticated();
     }
     $roles = $this->getRoles();
     return isset($roles[$roleIdentifier]);
 }
 /**
  * Sets a new password for the given user
  *
  * This method will iterate over all accounts owned by the given user and, if the account uses a UsernamePasswordToken,
  * sets a new password accordingly.
  *
  * @param User $user The user to set the password for
  * @param string $password A new password
  * @return void
  * @api
  */
 public function setUserPassword(User $user, $password)
 {
     $tokens = $this->authenticationManager->getTokens();
     $indexedTokens = array();
     foreach ($tokens as $token) {
         /** @var TokenInterface $token */
         $indexedTokens[$token->getAuthenticationProviderName()] = $token;
     }
     foreach ($user->getAccounts() as $account) {
         /** @var Account $account */
         $authenticationProviderName = $account->getAuthenticationProviderName();
         if (isset($indexedTokens[$authenticationProviderName]) && $indexedTokens[$authenticationProviderName] instanceof UsernamePassword) {
             $account->setCredentialsSource($this->hashService->hashPassword($password));
             $this->accountRepository->update($account);
         }
     }
 }