authentification.md 7.32 KB
Newer Older
1
2
# Authentification

3
## Types d'authentification
4

5
Quatre types d'authentification sont activables dans la configuration du module. 
6

7
1/ Authentification via la fédération d'identité Renater (Shibboleth)
8

9
10
11
- Ce type d'authentification requiert l'installation d'un module Shibboleth sur le serveur d'application, configuré
  pour se déclencher sur l'URL `/auth/shibboleth`, exemple : `https://sygal.univ.fr/auth/shibboleth`.
- Clé de configuration `shib`.
12

13
14
15
16
17
18
19
2/ Avec un compte local établissement (LDAP)

- La connexion à un annuaire LDAP est requise pour authentifier et récupérer les infos concernant l'utilisateur 
  (cf. configuration du module unicaen/app ou unicaen/ldap).
- Clé de configuration `ldap`.

3/ Avec un compte local propre à l'appli (DB) 
20
21
22

- Il peut arriver qu'une appli ait besoin d'authentifier des personnes n'existant pas dans l'annuaire LDAP.
- Pour donner accès à l'application à un nouvel utilisateur, 2 solutions :
23
24
  - Un informaticien crée à la main l'utilisateur dans la table des utilisateurs ; le mot de passe doit être chiffré 
    avec “Bcrypt” (exemple en ligne de commande à la racine de votre projet : 
Bertrand Gauthier's avatar
Bertrand Gauthier committed
25
    `php --run 'require "vendor/autoload.php"; $bcrypt = new Laminas\Crypt\Password\Bcrypt(); var_dump($bcrypt->create("azerty"));'`).
26
27
28
29
  - Si la fonctionnalité est activée (fournie par le module "zf-commons/zfc-user" dont dépend le module unicaen/auth), 
    l'utilisateur s'enregistre lui-même dans la table des utilisateurs via un formulaire de l'application (le lien figure 
    sous le formulaire de connexion à l'appli).
- Clé de configuration `db`.
30

31
4/ Via un serveur d'authentification centralisée (CAS)
32
33

- L'authentification est déléguée au serveur CAS grâce au module jasig/phpcas (bibliothèque phpCAS).
34
35
36
- NB: La connexion à l'annuaire LDAP est tout de même requise pour récupérer les infos concernant l'utilisateur 
  (cf. configuration du module unicaen/app).
- Clé de config `cas`.
37
38
39

## Événement UserAuthenticatedEvent

40
41
Si vous avez activé l'enregistrement automatique de l'utilisateur authentifié dans la base de données de votre 
application, la classe abstraite UnicaenAuth\Event\Listener\AuthenticatedUserSavedAbstractListener peut vous intéresser.
42

43
44
Elle vous procure un moyen de “faire quelque chose” juste avant que l'entité utilisateur (fraîchement authentifié 
via LDAP) ne soit persistée. L'idée est d'écouter un événement particulier déclenché lors du processus d'authentification de l'utilisateur.
45

46
47
*Attention! Cet événement est déclenché par l'authentification LDAP, mais pas par l'authentification à partir d'une 
table locale en base de données.*
48

49
50
*Si vous avez mis en place (en plus ou à la place de l'authentification LDAP) une authentification à partir d'une 
table locale, écoutez plutôt l'événement authentication.success déclenché par le module ZfcUser une fois que l'authentification a réussi. Exemple :*
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

Module.php

    public function onBootstrap(MvcEvent $e) {
        //...
        $e->getApplication()->getEventManager()->getSharedManager()->attach(
            "*",
            'authenticate.success',
            array($this, 'onUserLogin'),
            100
        );
    }   
    //...        
    public function onUserLogin( $e ) {
          if (is_string($identity = $e->getIdentity())) {
             // login de l'utilisateur authentifié
             $username = $identity;
             //...
          } else {
             // id de l'utilisateur authentifié dans la table
             $id = $identity;
             //...
          }
          //...
    }        

Exemple :

UserAuthenticatedEventListener.php

    namespace Application\Auth;
     
    use Application\Entity\Db\Role;
    use Application\Entity\Db\Utilisateur;
    use UnicaenAuth\Event\Listener\AuthenticatedUserSavedAbstractListener;
    use UnicaenAuth\Event\UserAuthenticatedEvent;
    use UnicaenAuth\Service\UserContext as UserContextService;
     
    class UserAuthenticatedEventListener extends AuthenticatedUserSavedAbstractListener
    {
        /**
         * @var Role
         */
        private $defaultRole;
     
        /**
         * @param Role $defaultRole
         */
        public function setDefaultRole(Role $defaultRole)
        {
            $this->defaultRole = $defaultRole;
        }
     
        /**
         * @var UserContextService
         */
        private $userContextService;
     
        /**
         * @param UserContextService $userContextService
         */
        public function setAuthUserContextService(UserContextService $userContextService)
        {
            $this->userContextService = $userContextService;
        }
     
        /**
         * @param UserAuthenticatedEvent $e
         */
        public function onUserAuthenticatedPrePersist(UserAuthenticatedEvent $e)
        {
            /** @var Utilisateur $utilisateur */
            $utilisateur = $e->getDbUser();
     
            // Attribue le profil par défaut à l'utilisateur connecté s'il n'en a aucun.
            if ($utilisateur->getRoles()->count() === 0 && $this->defaultRole) {
                $role = $this->defaultRole;
                $utilisateur->addRole($role);
            }
     
            // Le premier rôle trouvé sera celui endossé par l'utilisateur connecté.
            if ($role = $utilisateur->getRoles()->first()) {
                $this->userContextService->setNextSelectedIdentityRole($role);
            }
        }
    }

UserAuthenticatedEventListenerFactory.php

    namespace Application\Auth;
     
    use Application\Entity\Db\Role;
    use Doctrine\ORM\EntityManager;
    use UnicaenAuth\Service\UserContext as UserContextService;
Bertrand Gauthier's avatar
Bertrand Gauthier committed
145
    use Laminas\ServiceManager\ServiceLocatorInterface;
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
     
    class UserAuthenticatedEventListenerFactory
    {
        public function __invoke(ServiceLocatorInterface $serviceLocator)
        {
            /** @var EntityManager $em */
            $em = $serviceLocator->get('doctrine.entitymanager.orm_default');
     
            /** @var UserContextService $userContextService */
            $userContextService = $serviceLocator->get('AuthUserContext');
     
            /** @var Role $defaultRole */
            $defaultRole = $em->getRepository(Role::class)->findOneBy(['isDefault' => true]);
     
            $listener = new UserAuthenticatedEventListener();
            $listener->setDefaultRole($defaultRole);
            $listener->setAuthUserContextService($userContextService);
     
            return $listener;
        }
    }

Module.php

    namespace Application;
     
    use Application\Auth\UserAuthenticatedEventListener;
Bertrand Gauthier's avatar
Bertrand Gauthier committed
173
    use Laminas\Mvc\MvcEvent;
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
     
    class Module
    {
        public function onBootstrap(MvcEvent $e)
        {
            $application = $e->getApplication();
            $eventManager = $application->getEventManager();
     
            //...
     
            /** @var UserAuthenticatedEventListener $listener */
            $listener = $sm->get('UserAuthenticatedEventListener');
            $listener->attach($eventManager);
        }
        //...
    }    

module/Application/config/module.config.php

    return array(
        //...
        'service_manager' => array(
            'factories' => array(
                //...
                'UserAuthenticatedEventListener' => 'Application\Auth\UserAuthenticatedEventListenerFactory',
            ),
            //...
        ),
        //...
    );