Bundle d'authentification - Solution complète
Vu la taille des avirons que j'ai du sortir pour réaliser cette ébauche de module de sécurité totalement personnalisé,
j'ai pensé qu'une publication pourrait aider d'autres galériens...
L'objet est de faire un bundle qui présente un écran de login puis utilise un listener personnalisé,
un authenticationProvider, un UserProvider, un User, une Factory et tout le toutim. Avec les fichiers
de configuration qui vont bien.
Normalement, avec une application vierge, si l'on crée un Bundle avec
Code:
1 2
|
php app/console generate:bundle --namespace=Acme/SecurityBundle --format=yml |
Et que l'on copie le code ci-dessous, on doit obtenir un squelette de sécurité personnalisé qui fonctionne.
J'ai essayé autant que possible de personnaliser tout ce qui pouvait l'être.
Toute remarque ou suggestion qui permettrait d'améliorer la clarté et/ou la qualité de ce qui est proposé ci dessous est la bienvenue.
Tout d'abord un petit tour du circuit emprunté :
Le premier élément qui va être créé est la Factory. C'est dans cette factory que l'on va préciser le Listener
et le UserProvider que l'on compte utiliser. Pour que cela fonctionne, ils doivent être déclarés comme services
dans security.yml
Ensuite, le Listener et l'authenticationProvider seront initialisés.
À ce moment là, tout est prêt pour lancer l'action. Le loginAction est déclenché et le formulaire affiché.
L'action login_check lance la fonction attemptAuthentication du Listener.
Un jeton (Token) est créé, la fonction d'authentification (authenticate) du
UserProvider est exécutée et, en cas de succès, l'utilisateur correspondant est chargé et
son jeton authentifié (Token) est créé.
Et concrètement, ça donne quoi ?.
L'arborescence du Bundle :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
|~src/
| |~Acme/
| | `~SecurityBundle/
| | |~Controller/
| | | |-DefaultController.php
| | | `-SecurityController.php
| | |~DependencyInjection/
| | | |~Security/
| | | | `~Factory/
| | | | `-UserFactory.php
| | | |-AcmeSecurityExtension.php
| | | `-Configuration.php
| | |~Resources/
| | | |~config/
| | | | |-routing.yml
| | | | |-security_factories.yml
| | | | `-services.yml
| | | `~views/
| | | |~Default/
| | | | `-index.html.twig
| | | `~Login/
| | | `-login.html.twig
| | |~Security/
| | | |~Authentication/
| | | | |~Firewall/
| | | | | `-AuthListener.php
| | | | |~Provider/
| | | | | `-AuthProvider.php
| | | | `~Token/
| | | | `-UserToken.php
| | | `~User/
| | | |-User.php
| | | `-UserProvider.php
| | |+Tests/
| | `-AcmeSecurityBundle.php |
La factory :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
<?php
// src/Acme/SecurityBundle/DependencyInjection/Security/Factory/UserFactory.php
namespace Acme\SecurityBundle\DependencyInjection\Security\Factory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
class UserFactory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$providerId = 'security.authentication.provider.user.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('user.security.authentication.provider'))
->replaceArgument(0, new Reference($userProvider))
;
$listenerId = 'security.authentication.listener.user.'.$id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('user.security.authentication.listener'));
return array($providerId, $listenerId, $defaultEntryPoint);
}
public function getPosition()
{
return 'pre_auth';
}
public function getKey()
{
return 'my_user_factory'; // Utilisée dans app/config/security.yml
}
public function addConfiguration(NodeDefinition $node)
{}
} |
Le Listener :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
<?php
// Acme/SecurityBundle/Security/Firewall/AuthListener.php
namespace Acme\SecurityBundle\Security\Authentication\Firewall;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Acme\SecurityBundle\Security\Authentication\Token\UserToken;
// Lorsque l'on veut un formulaire de login, il faut hériter de AbstractAuthenticationListener
// L'implémentation de ListenerInterface ne convient pas dans ce cas.
class AuthListener extends AbstractAuthenticationListener
{
protected $securityContext;
protected $authenticationManager;
protected $httpUtils;
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $options = array())
{
parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, "user", array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'intention' => 'authenticate',
'post_only' => true,
), $options));
}
/**
* Performs authentication.
*
* @param Request $request A Request instance
*
* @return TokenInterface The authenticated token, or null if full authentication is not possible
*
* @throws AuthenticationException if the authentication fails
*/
protected function attemptAuthentication(Request $request)
{
$username = trim($request->get($this->options['username_parameter'], null, true));
$password = $request->get($this->options['password_parameter'], null, true);
//$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);
return $this->authenticationManager->authenticate(new UserToken($username, $password, $this->providerKey));
}
public function getHttpUtils()
{
return $this->httpUtils;
}
public function setHttpUtils($httpUtils)
{
$this->httpUtils = $httpUtils;
}
} |
L'authenticationProvider :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
<?php
// Acme/SecurityBundle/Security/Authentication/Provider/AuthProvider.php
namespace Acme\SecurityBundle\Security\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Acme\SecurityBundle\Security\Authentication\Token\UserToken;
class AuthProvider implements AuthenticationProviderInterface
{
private $userProvider;
private $cacheDir;
public function __construct(UserProviderInterface $userProvider, $cacheDir)
{
$this->userProvider = $userProvider;
$this->cacheDir = $cacheDir;
}
public function authenticate(TokenInterface $token)
{
$user = $this->userProvider->loadUserByUsername($token->getUsername());
// $userToken = new UserToken();
// $userToken->setUser($user);
// echo "it worked"; exit;
$newToken = new UserToken($token->getUser(), $token->getCredentials(), "user", array("ROLE_ADMIN"));
$username = $newToken->getUser();
if (empty($username)) {
throw new BadCredentialsException('Bad credentials :)');
}
//return $newToken;
if ($user && $this->validate()) {
$authenticatedToken = new UserToken($token->getUser(), $token->getCredentials(), "user", $user->getRoles());
$authenticatedToken->setUser($user);
return $authenticatedToken;
}
}
public function supports(TokenInterface $token)
{
return $token instanceof UserToken;
}
public function validate()
{
return true;
}
} |
Le UserToken :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
<?php
// Acme/SecurityBundle/Security/Authenticaion/Token/UserToken.php
namespace Acme\SecurityBundle\Security\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
/**
* UsernamePasswordToken implements a username and password token.
*
*/
class UserToken extends AbstractToken
{
private $credentials;
private $providerKey;
/**
* Constructor.
*
* @param string $user The username (like a nickname, email address, etc.)
* @param string $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param array $roles An array of roles
*
* @throws \InvalidArgumentException
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
{
parent::__construct($roles);
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
$this->setUser($user);
$this->credentials = $credentials;
$this->providerKey = $providerKey;
parent::setAuthenticated(count($roles) > 0);
}
/**
* {@inheritdoc}
*/
public function setAuthenticated($isAuthenticated)
{
if ($isAuthenticated) {
throw new \LogicException('Cannot set this token to trusted after instantiation.');
}
parent::setAuthenticated(false);
}
public function getCredentials()
{
return $this->credentials;
}
public function getProviderKey()
{
return $this->providerKey;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
parent::eraseCredentials();
$this->credentials = null;
}
public function serialize()
{
return serialize(array($this->credentials, $this->providerKey, parent::serialize()));
}
public function unserialize($str)
{
list($this->credentials, $this->providerKey, $parentStr) = unserialize($str);
parent::unserialize($parentStr);
}
} |
Le User Provider :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
<?php
// src/Acme/SecurityBundle/Security/User/UserProvider.php
namespace Acme\SecurityBundle\Security\User;
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;
use Acme\SecurityBundle\Security\User\User;
class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// make a call to your webservice here
// $userData = ...
// pretend it returns an array on success, false if there is no user
$user = new User();
$user->setUsername($username);
$user->setPassword("1234");
$user->setRoles(array("ROLE_ADMIN"));
return $user;
// if ($userData) {
// // $password = '...';
// // ...
//
// return new WebserviceUser($username, $password, $salt, $roles)
// } else {
// throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
// }
}
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());
}
public function supportsClass($class)
{
return $class === 'Acme\SecurityBundle\Security\User';
}
} |
Le User :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
<?php
// src/Acme/SecurityBundle/Security/User/User.php
namespace Acme\SecurityBundle\Security\User;
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface
{
private $username;
private $password;
private $salt;
private $roles;
public function getRoles()
{
return $this->roles;
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return $this->salt;
}
public function getUsername()
{
return $this->username;
}
public function setRoles($roles)
{
$this->roles = $roles;
}
public function setPassword($password)
{
$this->password = $password;
}
public function setSalt($salt)
{
$this->salt = $salt;
}
public function setUsername($username)
{
$this->username = $username;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
if (!$user instanceof User) {
return false;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->getSalt() !== $user->getSalt()) {
return false;
}
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
} |
Le paramétrage
Le routing du bundle :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
# Acme/SecurityBundle/Resources/config/routing.yml
AcmeSecurityBundle_homepage:
pattern: /
defaults: { _controller: AcmeSecurityBundle:Default:index }
login:
pattern: /login
defaults: { _controller: AcmeSecurityBundle:Security:login }
login_check:
pattern: /login_check |
La déclaration de la factory
Code:
1 2 3 4 5 6 7 8
|
# Acme/SecurityBundle/Resources/config/security_factories.yml
services:
security.authentication.factory.user:
class: Acme\SecurityBundle\DependencyInjection\Security\Factory\UserFactory
tags:
- { name: security.listener.factory } |
La déclaration des services :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
# Acme/SecurityBundle/Resources/config/services.yml
services:
user.security.authentication.provider:
class: Acme\SecurityBundle\Security\Authentication\Provider\AuthProvider
arguments: ["", %kernel.cache_dir%/security/nonces]
user.security.authentication.listener:
class: Acme\SecurityBundle\Security\Authentication\Firewall\AuthListener
arguments: [@security.context, @security.authentication.manager, @security.authentication.session_strategy, @security.http_utils]
tags:
- { name: monolog.logger, channel: security }
user_provider_service:
class: Acme\SecurityBundle\Security\User\UserProvider |
Le paramétrage au niveau de l'application :
Le routing général
Code:
1 2 3 4 5 6
|
# /app/config/routing.yml
AcmeSecurityBundle:
resource: "@AcmeSecurityBundle/Resources/config/routing.yml"
prefix: / |
Security...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
# app/config/security.yml
security:
factories:
- "%kernel.root_dir%/../src/Acme/SecurityBundle/Resources/config/security_factories.yml"
firewalls:
login:
pattern: ^/login$
security: false
checkpoint:
pattern: ^/
my_user_factory: true # Correspond à la valeur renvoyée par la fonction getKey de la factory que je souhaite utiliser
form_login:
login_path: /login
check_path: /login_check
logout:
path: /logout
target: /
encoders:
Acme\SecurityBundle\Entity\User: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
user_provider:
id: user_provider_service # défini dans le service.yml du bundle
access_control:
# - { path: ^/_internal, role: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
# - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/event/new, roles: ROLE_ADMIN }
# - { path: ^/hello, roles: ROLE_USER } |
Les contrôleurs et les templates
Le contrôleur de la page d'accueil...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<?php
// Acme/SecurityBundle/Controller/DefaultController.php
namespace Acme\SecurityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
// Je profite de l'occasion pour regarder le contexte... (à ne pas faire en prod :-) )
return $this->render('AcmeSecurityBundle:Default:index.html.twig',
array('parametres' => print_r($this->container->getParameterBag()->all(), true),
'request' => print_r($this->getRequest(),true)));
}
} |
et le template associé
Code:
1 2 3 4 5 6 7 8 9 10
|
{# Acme/SecurityBundle/Resources/views/Default/index.html.twig #}
Hello !
<pre>
Parametres
{{ parametres }}
Request
{{ request }}
</pre> |
Le contrôleur de la page de login
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
<?php
// src/Acme/SecurityBundle/Controller/SecurityController.php
namespace Acme\SecurityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
class SecurityController extends Controller
{
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
return $this->render('AcmeSecurityBundle:Login:login.html.twig', array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
} |
et le template associé
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
{# Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
{% if error %}
<div>{{ error.message }}</div>
{% endif %}
<form name="loginForm" action="{{ path('login_check') }}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="_username" />
<label for="password">Password:</label>
<input type="password" id="password" name="_password" />
{#
If you want to control the URL the user is redirected to on success (more details
below)
<input type="hidden" name="_target_path" value="/account" />
#}
<button type="submit">login</button>
</form>
</script --> |
Voilà. Je pense avoir fait le tour et j'espère que tout ça est suffisamment clair...
Amusez-vous bien :-)
Adaptation à la version 2.1 de Symfony
Adaptation à Symfony 2.1
En premier lieu, la définition du service n'est plus faite dans le fichier factories
Acme\SecurityBundle\Resources\config\security_factories.yml. Le fichier peut être supprimé.
Les services sont maintenant chargés automatiquement par la fonction build du bundle
SecurityBundle/AcmeSecurityBundle.php
Modification du paramétrage security.yml
Suppression du paramètre factories
Modification du provider : Le paramètrage à changé (ajout du chain_provider).
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
# AppConfig\security.yml
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
providers:
user_provider:
id: user_provider_service
chain_provider:
chain:
providers: user_provider
firewalls:
login:
pattern: ^/login$
security: false
logout:
pattern: ^/(logout$)
security: false
secured_area:
pattern: ^/
access_master_factory:
login_path: /login
check_path: /login_check
failure_path: /logouterreur |
Chargement de la factory
Création de la fonction build, qui charge la configuration de la sécurité et instancie le listener.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
<?php
// Acme\SecurityBundle\AcmeSecurityBundle.php
namespace Acme\SecurityBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\SecurityBundle\DependencyInjection\Security\Factory\AcmeFactory;
class AcmeSecurityBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$extension = $container->getExtension('security');
$extension->addSecurityListenerFactory(new AcmeFactory());
}
}
?> |
Initialisation du Listener et de l’authenticationProvider
Modification du service.yml
Ajout du paramètre @kernel au listener Acme.security.authentication.listener ( cf.
Acme\SecurityBundle\Security\Firewall\AcmeAuthenticationListener.php)
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
# Acme\SecurityBundle\Resources\config\services.yml
#...
services:
#...
Acme.security.authentication.listener:
class: Acme\SecurityBundle\Security\Authentication\Firewall\AcmeAuthenticationListener
arguments: [@security.context, @security.authentication.manager, @security.authentication.session_strategy, @security.http_utils, @logger, "", @kernel]
tags:
- { name: monolog.logger, channel: security }
#... |
Modificaiton du listener
Le passage de Sf 2.1 à 2.0 contient des modification dans l’interface AbstractAuthenticationListener :
L’ordre des paramètres est différent :
. succesHandler et failureHandler se trouvent avant $option.
. succesHandler et failureHandler sont OBLIGATIORES
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
<?php
// Acme\SecurityBundle\Security\Firewall\AcmeAuthenticationListener.php
// Sf 2.1
public function __construct(
SecurityContextInterface $securityContext,
AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy,
HttpUtils $httpUtils,
$providerKey,
AuthenticationSuccessHandlerInterface $successHandler,
AuthenticationFailureHandlerInterface $failureHandler,
array $options = array(),
LoggerInterface $logger = null,
EventDispatcherInterface $dispatcher = null)
//Sf 2.0
public function __construct(
SecurityContextInterface $securityContext,
AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy,
HttpUtils $httpUtils,
$providerKey,
array $options = array(),
AuthenticationSuccessHandlerInterface $successHandler = null,
AuthenticationFailureHandlerInterface $failureHandler = null,
LoggerInterface $logger = null,
EventDispatcherInterface $dispatcher = null)
?> |
La classe a donc été modifiée :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
<?php
// Acme\SecurityBundle\Security\Firewall\AcmeAuthenticationListener.php
// Ajout dépendances.
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
// Possibilité de passer par des Handlers si besoin ...
//use Acme\SecurityBundle\Security\Authentication\Handler\LoginSuccessHandler;
//use Acme\SecurityBundle\Security\Authentication\Handler\LoginFailureHandler;
use Acme\SecurityBundle\Security\Authentication\Token\AcmeToken;
// mise à jour du contruct
public function __construct(SecurityContextInterface $securityContext,
AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy,
HttpUtils $httpUtils, $logger, $options = array(), $httpKernel)
// appel au contructeur parent
parent::__construct( $securityContext, $authenticationManager, $sessionStrategy, $httpUtils, "Acme",
new DefaultAuthenticationSuccessHandler($httpUtils, $options),
new DefaultAuthenticationFailureHandler($httpKernel, $httpUtils, $options),
array_merge(array('username_parameter' => '_username',
'password_parameter' => '_password',
'intention' => 'authenticate',
'post_only' => true,
),
$options)
);
?> |
Modification (légère) du User
Modification du nom de la fonction equals :
Code:
1 2 3 4 5
|
// Acme\SecurityBundle\Security\User\AcmeUser.php
public function equals(UserInterface $user)
// devient
public function isEqualTo(UserInterface $user) |