eZ\Publish\Core\REST\Server\Security\RestAuthenticator::authenticate PHP Method

authenticate() public method

public authenticate ( Request $request )
$request Symfony\Component\HttpFoundation\Request
    public function authenticate(Request $request)
    {
        // If a token already exists and username is the same as the one we request authentication for,
        // then return it and mark it as coming from session.
        $previousToken = $this->tokenStorage->getToken();
        if ($previousToken instanceof TokenInterface && $previousToken->getUsername() === $request->attributes->get('username')) {
            $previousToken->setAttribute('isFromSession', true);
            return $previousToken;
        }
        $token = $this->attemptAuthentication($request);
        if (!$token instanceof TokenInterface) {
            if ($this->logger) {
                $this->logger->error('REST: No token could be found in SecurityContext');
            }
            throw new TokenNotFoundException();
        }
        $this->tokenStorage->setToken($token);
        $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, new InteractiveLoginEvent($request, $token));
        // Re-fetch token from SecurityContext since an INTERACTIVE_LOGIN listener might have changed it
        // i.e. when using multiple user providers.
        // @see \eZ\Publish\Core\MVC\Symfony\Security\EventListener\SecurityListener::onInteractiveLogin()
        $token = $this->tokenStorage->getToken();
        $user = $token->getUser();
        if (!$user instanceof EzUser) {
            if ($this->logger) {
                $this->logger->error('REST: Authenticated user must be eZ\\Publish\\Core\\MVC\\Symfony\\Security\\User, got ' . is_string($user) ? $user : get_class($user));
            }
            $e = new InvalidUserTypeException('Authenticated user is not an eZ User.');
            $e->setToken($token);
            throw $e;
        }
        // Check if newly logged in user differs from previous one.
        if ($this->isUserConflict($user, $previousToken)) {
            $this->tokenStorage->setToken($previousToken);
            throw new UserConflictException();
        }
        return $token;
    }

Usage Example

 public function testAuthenticatePreviousTokenNotUsernamePassword()
 {
     $username = '******';
     $password = '******';
     $existingToken = $this->getMock('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface');
     $existingToken->expects($this->once())->method('getUsername')->will($this->returnValue(__METHOD__));
     $request = new Request();
     $request->attributes->set('username', $username);
     $request->attributes->set('password', $password);
     $usernamePasswordToken = new UsernamePasswordToken($username, $password, self::PROVIDER_KEY);
     $authenticatedToken = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken')->disableOriginalConstructor()->getMock();
     $this->authenticationManager->expects($this->once())->method('authenticate')->with($this->equalTo($usernamePasswordToken))->will($this->returnValue($authenticatedToken));
     $this->eventDispatcher->expects($this->once())->method('dispatch')->with(SecurityEvents::INTERACTIVE_LOGIN, $this->equalTo(new InteractiveLoginEvent($request, $authenticatedToken)));
     $this->tokenStorage->expects($this->at(0))->method('getToken')->will($this->returnValue($existingToken));
     $this->tokenStorage->expects($this->at(1))->method('setToken')->with($authenticatedToken);
     $this->tokenStorage->expects($this->at(2))->method('getToken')->will($this->returnValue($authenticatedToken));
     $authenticatedUser = $this->createUser(456);
     $authenticatedToken->expects($this->once())->method('getUser')->will($this->returnValue($authenticatedUser));
     $this->assertSame($authenticatedToken, $this->authenticator->authenticate($request));
 }