symfony2在TokenStorage中找不到令牌

时间:2016-05-07 00:22:03

标签: php forms symfony authentication

我正在尝试使用SimpeFormAuthenticator通过oAuth使用我的API。但是,身份验证出了问题。

security.yml

security:
    encoders:
        AdminBundle\Security\ApiUser: plaintext
    providers:
        admin.api_user_provider:
            id: admin.api_user_provider
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:   ^/login$
            anonymous: ~
        admin:
            pattern: ^/
            provider: admin.api_user_provider
            simple_form:
                authenticator: admin.api_authenticator
                login_path: admin_login
                check_path: admin_login_check
    role_hierarchy:
        ROLE_FOO_SUPERADMIN : ROLE_FOO_ADMIN 
        ROLE_FOO_ADMIN : ROLE_FOO_USER
        ROLE_USER : IS_AUTHENTICATED_ANONYMOUSLY
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_FOO_ADMIN }

此配置按预期工作。

我的ApiAuthenticator

class ApiAuthenticator implements SimpleFormAuthenticatorInterface
{
    private $apiCaller;

    public function __construct($apiCaller)
    {
        $this->apiCaller = $apiCaller;
    }

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        // get roles from api server
        $user = $userProvider->loadUserByUsername($token->getAccessToken());
        return new ApiToken($user, $token, $providerKey, $user->getRoles());
    }

    public function supportsToken(TokenInterface $token, $providerKey)
    {
        return $token instanceof ApiToken && $token->getProviderKey() === $providerKey;
    }

    public function createToken(Request $request, $username, $password, $providerKey)
    {
        // create oauth access token
        $token = $this->apiCaller->createAccessToken($username, $password);

        if ($token === null) {
            throw new CustomUserMessageAuthenticationException('Invalid username or password');
        }

        return new ApiToken($username, $token, $providerKey);
    }
}

ApiToken类

class ApiToken extends AbstractToken
{
    private $token;
    private $providerKey;

    public function __construct($user, $token, $providerKey, array $roles = array())
    {
        parent::__construct($roles);

        if (empty($providerKey)) {
            throw new \InvalidArgumentException('$providerKey must not be empty.');
        }

        $this->setUser($user);
        $this->token = $token;
        $this->providerKey = $providerKey;

        parent::setAuthenticated(count($roles) > 0);
    }

    public function getAccessToken()
    {
        return $this->token->access_token;
    }

    public function getCredentials()
    {
        return $this->token;
    }

    public function getProviderKey()
    {
        return $this->providerKey;
    }
}

UserProvider

class ApiUserProvider implements UserProviderInterface
{
    private $apiCaller;

    public function __construct($apiCaller)
    {
        $this->apiCaller = $apiCaller;
    }

    public function loadUserByUsername($accessToken)
    {
        $me = $this->apiCaller->me($accessToken);

        return new ApiUser($me->username, $me->roles_unserialized);
    }

    public function refreshUser(UserInterface $user)
    {
        /*if (!$user instanceof WebserviceUser) {
            throw new UnsupportedUserException(
                sprintf('Instances of "%s" are not supported.', get_class($user))
            );
        }*/

        return $this->loadUserByUsername($user->getUsername());
    }

    public function supportsClass($class)
    {
        return $class === 'AdminBundle\Security\ApiUser';
    }
    }
}

但是,我将始终重定向到登录。在logs / dev.log中有以下条目:

[2016-05-07 02:39:14] security.INFO: User has been authenticated successfully. {"username":"admin@foo.de"} []
[2016-05-07 02:39:14] security.DEBUG: Fallback to the default authentication success handler. [] []
[2016-05-07 02:39:14] security.DEBUG: Stored the security token in the session. {"key":"_security_admin"} []
[2016-05-07 02:39:15] request.INFO: Matched route "admin_dashboard". {"route_parameters":{"_controller":"AdminBundle\\Controller\\DashboardController::indexAction","_route":"admin_dashboard"},"request_uri":"http://admin.foo.dev/app_dev.php/"} []
[2016-05-07 02:02:42] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): A Token was not found in the TokenStorage. at /var/www/foo-admin/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:53)"} []

任何人都可以帮助我吗?

最佳, 基督教

2 个答案:

答案 0 :(得分:1)

如果我使用

session:
    save_path: ~

而不是

session:
    handler_id:  session.handler.native_file
    save_path:   "%kernel.root_dir%/../var/sessions/%kernel.environment%"

用于会话处理,它按预期工作。任何人都知道,可能是什么问题?

答案 1 :(得分:0)

也许可以帮助文件.htaccess规则。

# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]