【发布时间】:2018-03-03 21:07:10
【问题描述】:
我想编写一个基本的登录表单,它通过向外部 REST API 发送请求来验证用户身份。如果凭据正确,外部 API 接收登录名/密码并返回 200(ok)。 但是,我无法通过 UserProviderInterface 实现它,因为外部 REST API 在回复中给了我密码。 (loadUserByUsername方法中无法填写用户密码)。
我在这里找到了一个有效的解决方案,但它使用了 Symfony 3 中已删除的类:Symfony2 custom connection by web service
我使用自定义 Authenticator 进行了测试,它只检查密码是否为“toto”,但我得到了一个重定向循环,并且我的虚拟 UserProvider 仍然被调用:
<?php
namespace AppBundle\Security\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterface;
class WebserviceAuthenticator implements SimpleFormAuthenticatorInterface
{
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$user = new WebserviceUser($token->getUsername(), $token->getCredentials(), null, ['ROLE_ADMIN']);
// HERE : call the external REST API
if ($token->getCredentials() === 'toto') {
$token = new UsernamePasswordToken(
$user,
$user->getPassword(),
'main',
$user->getRoles()
);
return $token;
}
throw new CustomUserMessageAuthenticationException('Invalid username or password');
}
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);
}
}
【问题讨论】:
-
你看过Guard Authentication了吗?这是一种超级灵活但仍然很容易创建自定义身份验证机制的方法。
-
是的。当我删除 UserProvider 的“refreshUser”实现时,我刚刚使它工作。现在,我这样做了: public function refreshUser(UserInterface $user) { if (!$user instanceof WebserviceUser) { throw new UnsupportedUserException( sprintf('Instances of "%s" is not supported.', get_class($user)) ); } 返回$用户; } 没有风险吗?
-
我觉得应该没问题。
-
谢谢你,它正在工作。你对这篇文章有什么想法吗? stackoverflow.com/questions/46368737/…
标签: symfony authentication login passwords