Symfony 3自定义表单密码验证器

时间:2016-02-17 16:25:18

标签: php authentication symfony

我正在尝试通过自定义表单密码身份验证器进行身份验证,我按照此页面上的Symfony示例进行操作:Custom Form Password Authenticator,我更改了一些代码段以提供我的身份验证逻辑。一切看起来都很完美......但是Symfony继续告诉我,我被认证为匿名......以下是代码:

我的自定义Athenticator:

class SippyAuthenticator implements SimpleFormAuthenticatorInterface
{
    private $sippyAccounts;

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

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $result = $this->sippyAccounts->login($token->getUsername(), $token->getCredentials());

        if($result->isError()) {
            throw new CustomUserMessageAuthenticationException('Invalid username or password');
        } else {
            $roles = array('ROLE_ACCOUNT');
            $user = new User($token->getUsername(), $token->getCredentials(), $roles);

            $tokenNew = new UsernamePasswordToken( $user, $user->getPassword(), $providerKey, $user->getRoles());
            return $tokenNew;
        }
    }

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

    public function createToken(Request $request, $username, $password, $providerKey)
    {
        return new UsernamePasswordToken($username, $password, $providerKey);
    }
}

这是我的security.yml:

security:
    providers:
        in_memory:
            memory: ~

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: ~
            simple_form:
                authenticator: sippy.authenticator
                login_path: login
                check_path: login
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/es/overview, roles: ROLE_ACCOUNT }

1 个答案:

答案 0 :(得分:0)

问题是我在没有调用$ userProvider的情况下生成了用户对象(因为我没有实现它),而symfony后来使用这个对象($ userProvider)来检索已经进行过验证的对象用户并将其放入会话中... UserProvider 类和修改后的 SippyAuthenticator

class SippyUserProvider implements UserProviderInterface
{
    private $sippyAccounts;

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

    public function loadUserByUsername($username)
    {
        $result = $this->sippyAccounts->informationByUsername($username);

        if (!$result->isError()) {
            $password = null;
            return new SippyUser($username, $password, null, array('ROLE_ACCOUNT'));
        }

        throw new UsernameNotFoundException(
            sprintf('Username "%s" does not exist.', $username)
        );
    }

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

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

    public function supportsClass($class)
    {
        return $class === 'AppBundle\Model\SippyUser';
    }
}

class SippyAuthenticator implements SimpleFormAuthenticatorInterface
{
    private $sippyAccounts;

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

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $result = $this->sippyAccounts->login($token->getUsername(), $token->getCredentials());

        if($result->isError()) {
            throw new CustomUserMessageAuthenticationException('Invalid username or password');
        } else {
            $user = $userProvider->loadUserByUsername($token->getUsername());

            $tokenNew = new UsernamePasswordToken( $user, $user->getPassword(), $providerKey, $user->getRoles());
            $tokenNew->setAttributes($token->getAttributes());
            return $tokenNew;
        }
    }

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

    public function createToken(Request $request, $username, $password, $providerKey)
    {
        return new UsernamePasswordToken($username, $password, $providerKey);
    }
}

我希望这个答案对其他人有帮助......