我有一个奇怪的行为:当抛出异常而我的用户断开连接时。
我使用SF3和用户提供商(基本SF身份验证)。 我抛出了异常,因此我被重定向到自定义错误页面。 这个问题发生在dev和prod environnement上。
我没有找到任何关于此的文档,你知道它为什么会发生以及如何解决这个问题吗?
这是我的代码:
表单身份验证器:
<?php
namespace AppBundle\Security;
use AppBundle\Security\User\UserProvider;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
/**
* Class FormAuthenticator
* @package AppBundle\Security\User
*/
class FormAuthenticator extends AbstractGuardAuthenticator
{
/**
* @var \Symfony\Component\Routing\RouterInterface
*/
private $router;
/**
* Default message for authentication failure.
*
* @var string
*/
private $failMessage = 'Invalid credentials';
/**
* Creates a new instance of FormAuthenticator
* FormAuthenticator constructor.
* @param RouterInterface $router
*/
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
/**
* {@inheritdoc}
*/
public function getCredentials(Request $request)
{
if ($request->getPathInfo() == '/login' && $request->isMethod('POST')) {
return [
'username' => $request->request->get('username'),
'password' => $request->request->get('password'),
];
}
return null;
}
/**
* {@inheritdoc}
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
if (!$userProvider instanceof UserProvider) {
return null;
}
try {
return $userProvider->loadUserByUsername($credentials['username']);
} catch (UsernameNotFoundException $e) {
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
}
/**
* {@inheritdoc}
*/
public function checkCredentials($credentials, UserInterface $user)
{
$passwordEncoder = new PasswordEncoderService();
$password = $passwordEncoder->encodePassword($user->getUsername(), $user->getEmail(), $credentials['password'], $user->getSalt());
if ($user->getPassword() === $password['encodedPassword']) {
return true;
}
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$url = $this->router->generate('home');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
$url = $this->router->generate('login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$url = $this->router->generate('login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function supportsRememberMe()
{
return true;
}
}
用户提供商:
<?php
namespace AppBundle\Security\User;
use AppBundle\Services\MawsHelper;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
/**
* Class UserProvider
* @package AppBundle\Security
*/
class UserProvider implements UserProviderInterface
{
/** @var MawsHelper $mawsHelper */
private $mawsHelper;
/**
* UserProvider constructor.
* @param MawsHelper $mawsHelper
*/
public function __construct(MawsHelper $mawsHelper)
{
$this->mawsHelper = $mawsHelper;
}
/**
* @param string $idUser
* @return User
*/
public function loadUserByUsername($idUser)
{
// make a call to your webservice here
$userData = $this->mawsHelper->getUserData($idUser);
// pretend it returns an array on success, false if there is no user
if ($userData) {
return new User($userData['id'], $userData['firstName'], $userData['lastName'], $userData['email'], $userData['login'], $userData['password'], $userData['salt'], $userData['active'], $userData['birthDate'], $userData['datePassword'], $userData['groups'], $userData['permissions'], $userData['preferences']);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $idUser)
);
}
/**
* @param UserInterface $user
* @return User
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $this->loadUserByUsername($user->getUsername());
}
/**
* @param string $class
* @return bool
*/
public function supportsClass($class)
{
return User::class === $class;
}
}
Security.yml;
security:
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
maws:
id: app.maws_user_provider
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
anonymous: ~
logout:
path: /logout
target: /
guard:
authenticators:
- form_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/administration/*, roles: ROLE_ADMINISTRATION }
- { path: ^/, roles: ROLE_ADMIN }
Service.yml:
# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/service_container.html
parameters:
#parameter_name: value
services:
#service_name:
# class: AppBundle\Directory\ClassName
# arguments: ['@another_service_name', 'plain_value', '%parameter_name%']
maws.exchange:
class: AppBundle\Services\RequestService
arguments: ['%dispatcher_host%']
maws.helper:
class: AppBundle\Services\MawsHelper
arguments: ['@maws.exchange']
session.service:
class: AppBundle\Services\SessionService
populate.session.service:
class: AppBundle\Services\PopulateSessionService
arguments: ['@maws.exchange']
app.local.action_listener:
class: AppBundle\EventListener\LocaleListener
arguments: ['en']
tags:
- { name: kernel.event_subscriber , priority: -257}
app.is_unique_validator:
class: AppBundle\Forms\Constraint\IsUniqueValidator
arguments: ['@maws.exchange']
tags:
- { name: validator.constraint_validator }
app.twig_extension:
class: AppBundle\Twig\AppExtension
public: true
tags:
- { name: twig.extension }
app.maws_user_provider:
class: AppBundle\Security\User\UserProvider
arguments: ['@maws.helper']
form_authenticator:
class: AppBundle\Security\FormAuthenticator
arguments: ["@router"]
app.user_locale_listener:
class: AppBundle\EventListener\UserLocaleListener
arguments: ['@session']
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }