Symfony2自定义用户提供程序在刷新后进行身份验证

时间:2014-01-09 14:20:41

标签: php security symfony service provider

您好我的问题是我设置自定义用户提供程序,当我想登录它时返回错误: there is no user provider for user

There is no user provider for user "MainBundle\Security\User\SsoUser".

但是当我按F5刷新页面时它会起作用! 为什么这是一个问题? 我的设置是:

    secured_area:
        pattern: ^/
        simple_preauth:
            authenticator: sso_authenticator

和我的autenticator类:

/**
 * @Service("sso_authenticator")
 */
class SsoAuthenticator implements SimplePreAuthenticatorInterface
{

    /**
     * @var SsoUserProvider
     */
    protected $userProvider;

    /**
     * @InjectParams({
     *      "userProvider" = @Inject("sso_user_provider")
     * })
     */
    public function __construct(SsoUserProvider $userProvider)
    {
        $this->userProvider = $userProvider;
    }

    public function createToken(Request $request, $providerKey)
    {
        $user = $request->getSession()->get('sso_user');

        if (!$user) {
            throw new BadCredentialsException('No user found');
        }

        return new PreAuthenticatedToken(
                'anon.', $user, $providerKey
        );
    }

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $user = $token->getCredentials();

        $sso_user = $this->userProvider->loadUser($user);

        return new PreAuthenticatedToken(
                $sso_user, $user, $providerKey, $sso_user->getRoles()
        );
    }

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

}

SsoUserProvider类:

/**
 * @Service("sso_user_provider")
 */
class SsoUserProvider implements UserProviderInterface
{

    public function loadUser($user)
    {
        return new SsoUser($user['id'], $user['username'], $user['password'], null, $user['email'], array('ROLE_USER'));
    }

    public function loadUserByUsername($username)
    {
        throw new \RuntimeException('Method unsupported');
    }

    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof SsoUser && !$this->supportsClass(get_class($user))) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }

        return $user;
    }

    public function supportsClass($class)
    {
        return $class === 'MainBundle\\Security\\User\\SsoUser';
    }

}

2 个答案:

答案 0 :(得分:2)

我编辑了这样的authenticateToken()方法,现在可以使用了:

public function authenticateToken(TokenInterface $ token,UserProviderInterface $ userProvider,$ providerKey) {     $ user = $ token-> getCredentials();     if(!is_array($ user)){         $ user = $ token-> getUser();     }

if (!$user) {
    throw new AuthenticationException('User does not exist.');
}

$ssoUser = $this->userProvider->loadUser($user);

return new PreAuthenticatedToken(
        $ssoUser, $user, $providerKey, $ssoUser->getRoles()
);

}

答案 1 :(得分:0)

您可以禁用这三行并再次检查是否发生此错误?

if (!$user instanceof SsoUser && !$this->supportsClass(get_class($user))) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }

我觉得$user类型可能存在问题或!$this->supportsClas< - 如果有'!'登录?