根据这个" Old"文章Is there any sort of "pre login" event or similar?我可以扩展UsernamePasswordFormAuthenticationListener以添加一些代码预登录。
在symfony3中似乎没有security.authentication.listener.form.class
参数,那么如何在不更改symfony security_listener.xml
配置文件的情况下获得相同的结果?
答案 0 :(得分:2)
要执行一些登录前/登录后检查(即用户身份验证之前/之后),Symfony框架提供的最简单灵活的解决方案之一是学习How to Create and Enable Custom User Checkers。
如果您需要更多控制和灵活性,最好的选择是学习How to Create a Custom Authentication System with Guard。 看一下下面的简单实现示例:
<强> security.yml 强>
firewall_name:
guard:
authenticators:
- service_name_for_guard_authenticator
entry_point: service_name_for_guard_authenticator <-- important to add a default one (as described in the docs) if you have many custom authenticators (facebook...)
<强> service.xml中强>
<service id="service_name_for_guard_authenticator"
class="AppBundle\ExampleFolderName\YourGuardAuthClassName">
<argument type="service" id="router"/>
<argument type="service" id="security.password_encoder"/>
</service>
<强> YourGuardAuthClassName.php 强>
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
class YourGuardAuthClassName extends AbstractGuardAuthenticator
{
private $router;
private $passwordEncoder;
public function __construct(
Router $router,
UserPasswordEncoder $passwordEncoder)
{
$this->router = $router;
$this->passwordEncoder = $passwordEncoder;
}
public function start(Request $request, AuthenticationException $authException = null)
{
$response = new RedirectResponse($this->router->generate('your_user_login_route_name'));
return $response;
}
public function getCredentials(Request $request)
{
# CHECK IF IT'S THE CHECK LOGIN ROUTE
if ($request->attributes->get('_route') !== 'your_user_login_route_name'
|| !$request->isMethod('POST')) {
return null;
}
# GRAB ALL REQUEST PARAMETERS
$params = $request->request->all();
# SET LOGIN CREDENTIALS
return array(
'email' => $params['email'],
'password' => $params['password'],
);
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$email = $credentials['email'];
$user = $userProvider->loadUserByUsername($email);
if (! $user){
throw new UsernameNotFoundException();
}
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
# YOU CAN ADD YOUR CHECKS HERE!
if (! $this->passwordEncoder->isPasswordValid($user, $credentials['password'])) {
throw new BadCredentialsException();
}
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
# OYU CAN ALSO USE THE EXCEPTIONS TO ADD A FLASH MESSAGE (YOU HAVE TO INJECT YOUR OWN FLASH MESSAGE SERVICE!)
if ($exception instanceof UsernameNotFoundException){
$this->flashMessage->error('user.login.exception.credentials_invalid');
}
if ($exception instanceof BadCredentialsException){
$this->flashMessage->error('user.login.exception.credentials_invalid');
}
return new RedirectResponse($this->router->generate('your_user_login_route_name'));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return new RedirectResponse($this->router->generate('your_success_login_route_name'));
}
public function supportsRememberMe()
{
return false;
}
}