Bonjour,

Dans l'optique de créer mon propre système d'authentification sur un AD (ldap), j'essaie de comprendre le mécanisme complet mis en œuvre sous symfony.

J'essaie pour le moment de créer le mécanisme de bas d'authentification sans aller cherche dans une quelconque base ou autre, l'idée est que le système me renvoie l'autorisation.

J'ai donc suivi de nombreux tuto/forum etc... Je me base maintenant essentiellement sur ça:

http://symfony.com/doc/current/cookbook/security/custom_provider.html


Mon projet est construit dans src/ADManager et j'ai un Bundle qui se nomme AuthenticationBundle
Voici toutes mes class et fichiers divers:

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
 
namespace ADManager\AuthentificationBundle\Controller;
 
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use ADManager\AuthentificationBundle\Controller\UserToken;
use AADManager\AuthentificationBundle\Controller\AuthenticationProvider;
 
class AuthenticationListener implements ListenerInterface
    {
    private $context;
    private $authManager;
 
    public function __construct(SecurityContextInterface $context, AuthenticationManagerInterface $authManager)
        {
        $this->context = $context;
        $this->authManager = $authManager;
        }
 
    /**
     * Handles access authorization.
     *
     * @param GetResponseEvent $event A GetResponseEvent instance
     */
    public function handle(GetResponseEvent $event)
        {
        $token = $this->context->getToken();
        if (null === $token) 
            {throw new AuthenticationCredentialsNotFoundException('A Token was not found in the SecurityContext.');}
 
        //$request = $event->getRequest();
 
        if (!$token->isAuthenticated()) 
            {
            $token = $this->authManager->authenticate($token);
            return $this->context->setToken($token);
            }
        else
            {
            return $this->context->setToken($token);
            }
        }
    }
le 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
 
namespace ADManager\AuthentificationBundle\Controller;
 
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use ADManager\AuthentificationBundle\Controller\UserToken;
 
class AuthenticationProvider implements AuthenticationProviderInterface
    {
    private $userProvider;
 
    public function __construct(UserProviderInterface $userProvider)
        {
        $this->userProvider = $userProvider;
        }
 
    public function authenticate(TokenInterface $token)
        {
        if(true)
            {
            $TokenAuthentifie = new UserToken("admin", "admin", "ADM", array('ROLE_ADMIN'));
            return $TokenAuthentifie;
            }
        throw new AuthenticationException('The WSSE authentication failed.');
 
        }
 
    public function supports(TokenInterface $token) 
        {return true;}
    }
Ma class 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
 
 
namespace ADM\AuthenticationBundle\Controller;
 
use Symfony\Component\Security\Core\User\UserInterface;
 
class User implements UserInterface
    {
    protected $username;
 
    protected $password;
 
    protected $roles;
 
    protected $groups;
 
    protected $salt;
 
    public function __construct($username, $password, $salt, array $roles)
        {
        $this->username = $username;
        $this->password = $password;
        $this->salt = $salt;
        $this->roles = $roles;
        //$this->groups = array();
        }
 
    public function equals(UserInterface $user) 
        {
        if (!$user instanceof WebserviceUser) {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;
        }
 
    public function eraseCredentials() 
        {$this->password = null;}
 
    public function setPassword($password)
        {$this->password = $password;}
    public function getPassword() 
        {return $this->password;}
 
    public function setRoles($roles)
        {$this->roles = $roles;}
    public function getRoles() 
        {return $this->roles;}
 
    public function setSalt($salt)
        {$this->salt = $salt;}
    public function getSalt() 
        {return $this->salt;}
 
    public function setUsername($username)
        {$this->username = $username;}
    public function getUsername() 
        {return $this->username;}
    }
mon 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
52
53
54
55
 
 
namespace ADM\AuthenticationBundle\Controller;
 
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 ADM\AuthenticationBundle\Controller\User;
 
class UserProvider implements UserProviderInterface
    {
    private $UserPWD;
 
    /**
     * Le password de l'utilisateur doit être au préalable enregistré via la fonction setUserPWD($userpwd)
     * @param type $username
     * @return \AdLdap\UserBundle\Security\User
     * @throws UsernameNotFoundException
     */
    public function loadUserByUsername($username) 
        {
        // Instanciation du LDAP
        //$ldap = $this->container->get('adldap_adldap');
        //$Liste_Roles = array();
        //if($ldap->authenticate($username, $UserPWD, false))
        //    {
        //    $Liste_Roles_Group = $this->container->getParameter('roles_groupes');
        //    foreach($Liste_Roles_Group as $roles => $group)
        //        {   
        //        if($ldap->user->inGroup($username, $group, NULL, false))
        //            {$Liste_Roles[] = $roles;}
        //        }
        //    return new User($username, $UserPWD, '', $roles);
        //    }   
        //else
        //    {throw new UsernameNotFoundException(sprintf('l\'utilisateur "%s" n\'existe pas.', $username));}
 
        return new User("admin", "admin", '', 'ROLE_ADMIN');
        }
 
    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 === 'AdLdap\UserBundle\Security\User';}
 
    public function setUserPWD($userpwd)
        {$UserPWD = $userpwd;}
    }
mon 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
 
namespace ADManager\AuthentificationBundle\Controller;
 
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
 
class AuthenticationToken extends AbstractToken implements TokenInterface
    {
    private $credentials;
    private $providerKey;
 
    /**
     * Constructor.
     *
     * @param string $user        The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
     * @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);
        }   
    }
mon service.yml de mon 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
 
parameters:
#    ad_manager_authentification.example.class: ADManager\AuthentificationBundle\Example
 
services:
    ADM.security.authentication.provider:
        class: ADManager\AuthentificationBundle\Controller\AuthenticationProvider
 
    ADM.security.user.provider:
        class: ADManager\AuthentificationBundle\Controller\UserProvider
 
    ADM.security.authentication.listener:
        class: ADManager\AuthentificationBundle\Controller\AuthenticationListener
        arguments: [@security.context, @security.authentication.manager]
 
    security.authentication.factory.ADM:
        class:  ADManager\AuthentificationBundle\Factory\AuthenticationFactory
        tags:
            - { name: security.listener.factory }
mon security_factories.yml:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
services:
    security.authentication.factory.ADM:
        class:  ADManager\AuthentificationBundle\Factory\AuthenticationFactory
        tags:
            - { name: security.listener.factory }
mon routing.yml:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
_security_login:
    pattern:  /login
    defaults: { _controller: ADMAuthenticationBundle:Authentication:login }
 
_security_check:
    pattern:  /login_check  
 
_security_logout:
    pattern:  /logout
le security.yml de app/config:

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
 
security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
 
    factories:
        - "%kernel.root_dir%/../src/ADManager/AuthentificationBundle/Resources/config/security_factories.yml"
 
    role_hierarchy:
 
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
 
    providers:
        in_memory:
            users:
                user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
        ADM_provider:
            id: ADM.security.user.provider
 
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
 
        login:
            pattern:  ^/demo/secured/login$
            security: false
 
        ADM_provider:
            pattern: ^/DSI/.*
            provider: ADM.provider
            form_login:
                check_path: _security_check
                login_path: _security_login
            logout:
                path: _security_logout
                target: /DSI/index        #Mettre ici la route vers votre page d'accueil
            #security: true
            ADM: true
            anonymous: false
 
    access_control:
        #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        #- { path: ^/_internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
les routes sont bien sure déclarées tout comme le bundle.

Je vous passe les vues..

J'ai déjà réussi à débuguer pas mal d'erreur mais la je bloque...

lorsque j'essaie mon url voici le message d'erreur:

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
 
 
Whoops, looks like something went wrong.
1/1 OutOfBoundsException: The index "0" is not in the range [0, -1].
 
    in /MOUNT/WWW/Dsi-Symfony/vendor/symfony/src/Symfony/Component/DependencyInjection/Definition.php line 248
    at Definition->replaceArgument() in /MOUNT/WWW/Dsi-Symfony/vendor/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php line 124
    at ResolveDefinitionTemplatesPass->resolveDefinition() in /MOUNT/WWW/Dsi-Symfony/vendor/symfony/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php line 49
    at ResolveDefinitionTemplatesPass->process() in /MOUNT/WWW/Dsi-Symfony/vendor/symfony/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php line 119
    at Compiler->compile() in /MOUNT/WWW/Dsi-Symfony/vendor/symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php line 437
    at ContainerBuilder->compile() in /MOUNT/WWW/Dsi-Symfony/app/bootstrap.php.cache line 872
    at Kernel->buildContainer() in /MOUNT/WWW/Dsi-Symfony/app/bootstrap.php.cache line 783
    at Kernel->initializeContainer() in /MOUNT/WWW/Dsi-Symfony/app/bootstrap.php.cache line 517
    at Kernel->boot() in /MOUNT/WWW/Dsi-Symfony/app/bootstrap.php.cache line 548
    at Kernel->handle() in /MOUNT/WWW/Dsi-Symfony/web/app_dev.php line 28
Je précise aussi que dans mon services.yml, netbeans me signal ceci à la ligne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
ADM.security.authentication.listener:
        class: ADManager\AuthentificationBundle\Controller\AuthenticationListener
        arguments: [@security.context, @security.authentication.manager]
"ScannerException while scanning for the next token we had this found character @(64) that cannot start any token"

voilà j'espère avoir donner assez d'info, j'espère que quelqu'un pourra m'aiguiller

merci d'avance