symfony login custom webservice

2019-07-25 08:01发布

I was working on custom web service authentication, that requires username as password combination, like this "username_password" to be passed via POST method.
Here's what I'v got: I created Web service User, and User provider classes, by following this documentation, and configured security.yml according to this guide.
But since I need to pass password to UserProvider, I folowed this solution provided in answer, by passing request service to UserProvider class and got this:

class WebserviceUserProvider implements UserProviderInterface
{
    private $request;
    private $buzz;
    private $password;

    public function __construct(ContainerInterface $container)
    {
        $this->request = $container->get('request');
        $this->buzz = $container->get('buzz');
    }

    public function loadUserByUsername($username)
    {
        if ($this->request->get('_password')) {
            $this->password = $this->request->get('_password');
        }

        //remote air.salda.lt login service
        $userData = $this->buzz->post(
            'http://remote.service.url', 
            array(), 
            array("UID" => $username.'_'.$this->password)
        );

        if ($userData->getContent() == 'OK') {
            $password = $this->password;
            $salt = ''; 

            //here should be additional logic to fetch user roles from db, specific to application 

            $roles = array('ROLE_USER');

            return new WebserviceUser($username, $password, $salt, $roles);
        }

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

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

        $this->password = $user->getPassword();

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

    public function supportsClass($class)
    {
        return $class === 'Cc\ClientControlBundle\Security\User\WebserviceUser';
    }
}

Notice in "loadUserByUsername" method

if ($this->request->get('_password')) {
    $this->password = $this->request->get('_password');
}

And in "refreshUser" method

$this->password = $user->getPassword();

I done this because, when getting password from request first time it works fine, but when "refreshUser" happens, request object seems to be missing password, so by saving password globally in a class, I can access it later.

This solution works, but to me it's seems like a hack, I would really like to solve this problem properly, but I don't know how, maybe by using Custom Authenticator Provider? Thought it seems really complicated. Some advices and guidance would help.

0条回答
登录 后发表回答