我想用Symfony / Security对我的应用程序实施表单登录。我完成了所有配置,但仍然无法正常工作。
这是我的 security.yaml :
security:
providers:
sablon_users:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_login:
anonymous: true
pattern: ^/admin/auth
form_login:
login_path: security_login
check_path: security_login
csrf_token_generator: security.csrf.token_manager
default_target_path: /admin
admin:
pattern: ^/admin
guard:
authenticators:
- App\Security\LoginAuthenticator
provider: sablon_users
logout:
path: admin_logout
target: security_login
main:
pattern: ^/
anonymous: true
# activate different ways to authenticate
# http_basic: true
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: true
# https://symfony.com/doc/current/security/form_login_setup.html
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/admin/auth/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: IS_AUTHENTICATED_FULLY }
encoders:
App\Entity\User:
algorithm: bcrypt
cost: 12
我的 routes.yaml :
admin_logout:
path: /admin/auth/logout
admin:
type: annotation
resource: ../src/Controller/Admin
prefix: /admin
site:
type: annotation
resource: ../src/Controller/Site
LoginAuthenticator.php :
class LoginAuthenticator extends AbstractFormLoginAuthenticator
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var RouterInterface
*/
private $router;
/**
* @var UserPasswordEncoderInterface
*/
private $encoder;
/**
* @var CsrfTokenManagerInterface
*/
private $csrfTokenManager;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* LoginAuthenticator constructor.
*
* @param EntityManagerInterface $em
* @param CsrfTokenManagerInterface $csrfTokenManager
* @param RouterInterface $router
* @param TokenStorageInterface $tokenStorage
* @param UserPasswordEncoderInterface $encoder
*/
public function __construct(
EntityManagerInterface $em,
CsrfTokenManagerInterface $csrfTokenManager,
RouterInterface $router,
TokenStorageInterface $tokenStorage,
UserPasswordEncoderInterface $encoder
)
{
$this->em = $em;
$this->csrfTokenManager = $csrfTokenManager;
$this->router = $router;
$this->tokenStorage = $tokenStorage;
$this->encoder = $encoder;
}
/**
* @param Request $request
* @return bool
*/
/**
* @return mixed
*/
public function getCurrentUser()
{
$token = $this->tokenStorage->getToken();
return $token->getUser();
}
/**
* Does the authenticator support the given Request?
*
* If this returns false, the authenticator will be skipped.
*
* @param Request $request
*
* @return bool
*/
public function supports(Request $request)
{
$isLoginSubmitRequest = $request->getPathInfo() === 'admin/auth/login' && $request->isMethod('POST');
if(!$isLoginSubmitRequest){
return false;
}
return true;
}
/**
* @param Request $request
*
* @return mixed Any non-null value
*
* @throws \UnexpectedValueException If null is returned
*/
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
/**
* @param mixed $credentials
* @param UserProviderInterface $userProvider
* @return User|null|object|UserInterface
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
$user = $this->em->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);
if (!$user) {
// fail authentication with a custom error
throw new Exception('Email could not be found.');
}
return $user;
}
/**
* @param mixed $credentials
* @param UserInterface $user
*
* @return bool
*
* @throws AuthenticationException
*/
public function checkCredentials($credentials, UserInterface $user)
{
$password = $credentials['password'];
return $this->encoder->isPasswordValid($user,$password);
}
/**
*
* @param Request $request
* @param AuthenticationException $exception
*
* @return Response|null
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
return new RedirectResponse($this->router->generate('security_login'));
}
/**
* @param Request $request
* @param TokenInterface $token
* @param string $providerKey The provider (i.e. firewall) key
*
* @return Response|null
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return new RedirectResponse($this->router->generate('app_homepage'));
}
/**
* @return bool
*/
public function supportsRememberMe()
{
return false;
}
/**
* Return the URL to the login page.
*
* @return string
*/
protected function getLoginUrl()
{
return $this->router->generate('security_login');
}
当我尝试使用正确的凭据登录时。它将加载User,甚至在_profiler上显示已通过身份验证的用户名(令牌类:UsernamePasswordToken)。它显示了用户的相应角色。
但是,当我尝试浏览“ / admin”区域时,它会将我重定向到登录页面。它不会在页面或控制台中显示任何错误。
我的dev.log显示了流程:
答案 0 :(得分:0)
我遇到了同样的问题:消息说“ Guard Authenticator不支持该请求。”,在我的情况下,问题是我使用https而不是使用.htaccess中的http的symfony。
就我而言,解决方案就像访问https网页一样简单: -https://localhost/login
一旦登录成功。