简体   繁体   English

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

[英]Symfony 3 Custom Form Password Authenticator

I'm trying to authenticating via the Custom Form Password Authenticator , I follow the Symfony Example at this page: Custom Form Password Authenticator , I changed a few snippet for put my authentication logic. 我试图通过“ 自定义表单密码验证器”进行身份验证 ,并按照此页面上的Symfony示例进行操作:“ 自定义表单密码验证器” ,我更改了一些代码片段以放入验证逻辑。 All seem to work perfectly... But Symfony continued telling me that I'm authenticated as anonymous... Here is the code: 一切似乎都正常运行...但是Symfony继续告诉我,我已通过匿名身份验证...这是代码:

My Custom Athenticator: 我的自定义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);
    }
}

This is my security.yml: 这是我的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 }

The problem was that I was generating the User object without call the $userProvider (because I didn't implement it), and symfony later use this object ($userProvider) to retrive the already autenticated user and put it in the session... Below the UserProvider class and the modified SippyAuthenticator : 问题是我没有调用$ userProvider就生成了User对象(因为我没有实现它),而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);
    }
}

I hope this answer helpful to someone else... 我希望这个答案对其他人有帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM