public function authenticateToken(
        TokenInterface $token,
        UserProviderInterface $userProvider,
        $providerKey
    ) {
        $username = $token->getCredentials();
        $roles    = array_map(array($this, 'objectRolesToArray'), $token->getRoles());
        $user     = false;

        // If no username in Strategy, check if required.
        if ($this->securityRequired && !$username) {
            $this->logger->warning('Authentication key is required.');
            throw new AuthenticationException('Authentication key is required.');
        }

        if ($username) {
            if (in_array(SecurityUser::ROLE_SUBNET, $roles)) {
                $this->logger->info('Authentication, subnet user IP address: ' . $token->getAttribute('ipAddress'));
                $user = new SubnetUser($username);
            } elseif ($user = $this->userProvider->loadUserByUsername($username)) {
                $roles[] = SecurityUser::ROLE_CONSULTANT;
            }
        }

        // If no user, try to fetch the test user, else check if anonymous is enabled
        if (!$user) {
            if ($this->testUsername && $user = $this->userProvider->loadUserByUsername($this->testUsername)) {
                $this->logger->info('Authentication, test user: ' . $this->testUsername);
                $roles[] = SecurityUser::ROLE_TEST;
            } elseif ($this->allowAnonymous) {
                $this->logger->info('Authentication, loading anonymous user.');
                $user = new AnonymousUser();
                $roles[] = SecurityUser::ROLE_ANONYMOUS;
            }
        }

        /** @var SecurityUser $securityUser */
        if ($user) {
            $securityUser = new SecurityUser($user, $roles);
        } else {
            $this->logger->warning(sprintf('Authentication key "%s" could not be resolved.', $username));
            throw new AuthenticationException(
                sprintf('Authentication key "%s" could not be resolved.', $username)
            );
        }

        return new PreAuthenticatedToken(
            $securityUser,
            $username,
            $providerKey,
            $securityUser->getRoles()
        );
    }