IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Bundle d'authentification - Solution complète


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    423
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 423
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # /app/config/routing.yml
     
    AcmeSecurityBundle:
        resource: "@AcmeSecurityBundle/Resources/config/routing.yml"
        prefix:   /
    Security...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 :-)

  2. #2
    Membre éprouvé Avatar de anta_res
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2006
    Messages : 93
    Par défaut
    Et bien chapeau bas Mr fatbob.

    Je pense que ce post va aider un paquet de monde vu la galère que c'est de mettre en place un système d'authentification personnalisé.
    J'ai pas lu tout le code à fond mais ça m'a l'air propre et je pense que ça fait déjà un bon point départ pour tout ceux qui comme nous vont sortir les rames pour essayer de créer leur propre authentification.

  3. #3
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    423
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 423
    Par défaut
    Merci.
    N'hésite pas à corriger, ou préciser des éléments (en particulier pour clarifier certaines interactions). Je suis assez nouveau avec symfony et c'est un peu mon baptême du feu... J'ai sans doute oublié des trucs.

  4. #4
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2012
    Messages : 21
    Par défaut Mon
    Bonjour,

    Vraiment merci pour ta super doc.

    Par contre, pour que cela marche correctement, j'ai du mettre parent::setAuthenticated(true); au lieu de parent::setAuthenticated(false);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
         // Fichier AuthProvider.php
         public function setAuthenticated($isAuthenticated)
        {
            if ($isAuthenticated) {
                throw new \LogicException('Cannot set this token to trusted after instantiation.');
            }
     
            parent::setAuthenticated(true);
        }
    Si je laisse à false dans mon profiler j'ai : "username" (no auth.) et je ne peux pas faire mes tests dans mon controleur pour voir si l'utilisateur a bien l'autorisation

  5. #5
    Rédacteur
    Avatar de Viduc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2009
    Messages
    1 445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2009
    Messages : 1 445
    Billets dans le blog
    2
    Par défaut
    Salut et félicitation également!

    une petite correction à apporter dans ton securitycontroller tu as mis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     return $this->render('AcmeSecurityBundle:Login:login.html.twig', array(
    alors que ce doit être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
    C'est coole je vais enfin avoir une bonne base pour avancer!!! encore merci à toi

  6. #6
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    423
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 423
    Par défaut
    @Viduc : Exact... Malheureusement, je ne peux pas éditer mon post...
    @ray-k : c'est étrange. Chez moi ça fonctionne bien comme ça. Mettre true dans le parent::setAuthenticated me semble curieux dans la mesure où juste avant, on dit : "Si le paramètre est à true, balancer l'exception comme quoi on n'authentifie pas ce token après sa création", or c'est ce que tu fais en mettant true...

Discussions similaires

  1. Quelle solution complète PME: ADSL, Parfeu, VPN et Backup
    Par geekforever dans le forum Hardware
    Réponses: 1
    Dernier message: 23/02/2011, 22h52
  2. Réponses: 0
    Dernier message: 22/09/2010, 22h52
  3. Réponses: 0
    Dernier message: 21/06/2010, 13h49
  4. Recherche de solution complète de mise en marché
    Par Vol dans le forum E-Commerce
    Réponses: 2
    Dernier message: 04/01/2009, 05h53
  5. Assistant d'import d'une solution complète
    Par SaumonAgile dans le forum Dreamshield
    Réponses: 3
    Dernier message: 03/09/2007, 23h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo