由于某些特殊需要,我想按照Symfony文档(https://symfony.com/doc/current/security/form_login_setup.html)中的说明在我的Symfony App中使用Guard Authenticator。从身份验证器中的各种变量转储中可以看到,身份验证器的工作原理。但是在重定向之后,身份验证令牌接缝将丢失,我将再次重定向到登录表单。
Authenticator(用于调试问题的简化版本):
<?php
namespace App\Security;
// use statements omitted
class LoginFormAuthenticatorSimple extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $router;
private $csrfTokenManager;
public function __construct(RouterInterface $router,
CsrfTokenManagerInterface $csrfTokenManager)
{
$this->router = $router;
$this->csrfTokenManager = $csrfTokenManager;
}
public function supports(Request $request)
{
return 'login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
'username' => $request->request->get('username'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['username']
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface $userProvider) {
$user = new User();
$user->setUid("jensp");
$roles = ['ROLE_USER'];
$user->setRoles($roles);
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
$username = $credentials["username"];
$password = $credentials["password"];
if ('' === (string) $password) {
throw new BadCredentialsException('The presented password must not be empty.');
}
return $username === "jensp" && $password === "test123";
}
public function createAuthenticatedToken(UserInterface $user, $providerKey)
{
// Added to check if the token is created...
dump($user);
dump($providerKey);
$token = parent::createAuthenticatedToken($user, $providerKey);
dump($token);
return $token;
}
public function onAuthenticationSuccess(Request $request,
TokenInterface $token,
$providerKey)
{
dump($token);
dump($request);
if ($targetPath = $this->getTargetPath($request->getSession(),
$providerKey)) {
dump($targetPath);
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->router->generate('show_users'));
}
protected function getLoginUrl()
{
return $this->router->generate('login');
}
security.yaml:
firewalls:
main:
pattern: ^/(users|groups|selfservice|login_check|form_login_ldap|login)
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\LoginFormAuthenticatorSimple
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/users, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/groups, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/self-service, roles: IS_AUTHENTICATED_FULLY }
有没有暗示用户不保持身份验证的方式?
答案 0 :(得分:2)
问题是您的getUser
方法。您在此处创建一个新的User对象,而不是返回数据库(或存储用户信息的位置)中已有的对象。
尝试以下方法:
public function getUser($credentials, UserProviderInterface $userProvider): UserInterface
{
try {
$userProvider->loadUserByUsername($credentials['username']);
} catch (UsernameNotFoundException $e) {
throw new AuthenticationException('Username or password is wrong.');
}
}
通过这种方式,您将使用注入的$userProvider
来获取您已通过身份验证的用户。
侧面说明:您无需在会话中存储任何用户数据。您可以在控制器和服务中使用TokenStorageInterface
来获取当前经过身份验证的用户。