Bonjour à tous,
Développant une application nécessitant une authentification sur un Active Directory, j'ai opté pour le couple FOSUserBundle et IMAGLdapBundle (FR3DLdapBundle n'étant visiblement plus maintenu). J'ai donc suivi la doc pour le paramétrage des bundles et étendu la classe User de FOSUserBundle pour y ajouter des attributs, ce qui me donne la configuration suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13# config.yml fos_user: db_driver: orm firewall_name: main user_class: Acme\UserBundle\Entity\User group: group_class: Acme\UserBundle\Entity\Group group_manager: sonata.user.orm.group_manager service: user_manager: sonata.user.orm.user_manager
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 # security.yml security: ... encoders: Acme\UserBundle\Entity\User: plaintext firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: pattern: ^/ provider: ldap anonymous: ~ imag_ldap: ~ logout: path: /logout target: / providers: ldap: id: imag_ldap.security.user.provider imag_ldap: client: host: 127.0.0.1 port: 10389 referrals_enabled: false skip_roles: true version: 3 user: base_dn: DC=test, DC=fr filter: (&(objectClass=person)) name_attribute: sn role: base_dn: DC=test, DC=fr filter: (&(ObjectClass=group)) name_attribute: sn user_attribute: member user_class: Acme\UserBundle\Entity\User
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #services.yml services: imag_ldap.security.user.provider: class: Acme\UserBundle\Security\User\Provider\LdapUserProvider arguments: - @service_container - @imag_ldap.ldap_manager - @fos_user.user_manager - @validator - %imag_ldap.model.user_class%
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
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
145
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 <?php // Acme\UserBundle\Entity\User namespace Acme\UserBundle\Entity; use Doctrine\ORM\Mapping as ORM; use FOS\UserBundle\Entity\User as BaseUser; use IMAG\LdapBundle\User\LdapUserInterface; use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity * @ORM\Table(name="person") */ class User extends BaseUser implements LdapUserInterface { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(name="cn", type="string", length=255) */ protected $cn; /** * @ORM\Column(name="dn", type="string", length=255) */ protected $dn; /** * @ORM\Column(name="thumbnail", type="string", length=255) */ protected $thumbnail; /** * @ORM\ManyToOne(targetEntity="Acme\OrgBundle\Entity\Department") * @ORM\JoinColumn(name="department_id", referencedColumnName="id") */ protected $department; /** * @ORM\ManyToMany(targetEntity="Acme\UserBundle\Entity\Group") * @ORM\JoinTable(name="persons_permissions", * joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")} * ) */ protected $groups; protected $attributes; public function getDn() { return $this->dn; } public function setDn($dn) { $this->dn = $dn; return $this; } public function getCn() { return $this->cn; } public function setCn($cn) { $this->cn = $cn; return $this; } public function getThumbnail() { return $this->thumbnail; } public function setThumbnail($thumbnail) { $this->thumbnail = $thumbnail; return $this; } /** * Set department * * @param \Acme\OrgBundle\Entity\Department $department * @return Convention */ public function setDepartment(\Acme\OrgBundle\Entity\Department $department) { $this->department = $department; return $this; } /** * Get department * * @return \Acme\OrgBundle\Entity\Department */ public function getDepartment() { return $this->department; } public function getAttributes() { return $this->attributes; } public function setAttributes(array $attributes) { $this->attributes = $attributes; return $this; } public function getAttribute($name) { return isset($this->attributes[$name]) ? $this->attributes[$name] : null; } public function isEqualTo(UserInterface $user) { if (!$user instanceof LdapUserInterface || $user->getUsername() !== $this->username || $user->getEmail() !== $this->email || count(array_diff($user->getRoles(), $this->getRoles())) > 0 || $user->getDn() !== $this->dn ) { return false; } return true; } public function serialize() { return serialize(array( $this->password, $this->salt, $this->usernameCanonical, $this->username, $this->emailCanonical, $this->email, $this->expired, $this->locked, $this->credentialsExpired, $this->enabled, $this->roles, $this->id, $this->cn, $this->dn, $this->thumbnail, )); } public function unserialize($serialized) { list( $this->password, $this->salt, $this->usernameCanonical, $this->username, $this->emailCanonical, $this->email, $this->expired, $this->locked, $this->credentialsExpired, $this->enabled, $this->roles, $this->id, $this->cn, $this->dn, $this->thumbnail, ) = unserialize($serialized); } }Le comportement d'authentification est conforme à mes attentes : lors d'une première connexion, l'utilisateur est bien ajouté en base de données. L'administrateur doit alors lui attribuer un rôle afin qu'il puisse accéder à l'application.
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 <?php // Acme\UserBundle\Security\User\Provider\LdapUserProvider namespace Acme\UserBundle\Security\User\Provider; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException, Symfony\Component\Security\Core\Exception\UnsupportedUserException, Symfony\Component\Security\Core\User\UserProviderInterface, Symfony\Component\DependencyInjection\ContainerInterface, Symfony\Component\Security\Core\User\UserInterface; use IMAG\LdapBundle\Manager\LdapManagerUserInterface, IMAG\LdapBundle\User\LdapUserInterface; use FOS\UserBundle\Model\UserManagerInterface; class LdapUserProvider implements UserProviderInterface { /** * @var \Symfony\Component\DependencyInjection\ContainerInterface */ private $container; /** * @var \IMAG\LdapBundle\Manager\LdapManagerUserInterface */ private $ldapManager; /** * @var \FOS\UserBundle\Model\UserManagerInterface */ protected $userManager; /** * @var \Symfony\Component\Validator\Validator */ protected $validator; /** * Constructor * * @param ContainerInterface $container * @param LdapManagerUserInterface $ldapManager * @param UserManagerInterface $userManager * @param Validator $validator */ public function __construct(ContainerInterface $container, LdapManagerUserInterface $ldapManager, UserManagerInterface $userManager, $validator) { $this->container = $container; $this->ldapManager = $ldapManager; $this->userManager = $userManager; $this->validator = $validator; } /** * {@inheritdoc} */ public function loadUserByUsername($username) { if (empty($username)) { throw new UsernameNotFoundException('The username is not provided.'); } $user = $this->userManager->findUserBy(array("username" => $username)); if(empty($user) && !$this->ldapManager->exists($username)) { throw new UsernameNotFoundException(sprintf('User "%s" not found', $username)); } $lm = $this->ldapManager->setUsername($username)->doPass(); if (empty($user)) { $user = $this->userManager->createUser(); $user ->setUsername($lm->getUsername()) ->setPassword("") ->setDn($lm->getDn()) ->setCn($lm->getCn()) ->setEmail($lm->getEmail()) ->setThumbnail($this->getThumbnail($lm->getUsername())); $this->userManager->updateUser($user); } return $user; } /** * {@inheritdoc} */ public function refreshUser(UserInterface $user) { if (!$user instanceof LdapUserInterface) { throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); } return $this->loadUserByUsername($user->getUsername()); } /** * {@inheritdoc} */ public function supportsClass($class) { return $this->userManager->supportsClass($class); } ... }
Mon problème tient au fait que les flags de compte ajoutés par FOSUser (enabled, locked, expired) ne sont jamais pris en compte lors de l'authentification, ce qui fait que le seul moyen de bloquer l'accès d'un utilisateur à l'application est de le supprimer complètement. Existe-t-il un moyen de faire fonctionner ces attributs en conjonction avec mon bundle LDAP ?
Merci par avance.
Partager