ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilAuthProviderLDAP.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27{
29 private string $migration_account = '';
30 private bool $force_new_account = false;
31
32 public function __construct(ilAuthCredentials $credentials, int $a_server_id = 0)
33 {
35 $this->initServer($a_server_id);
36 }
37
38 public function getServer(): ilLDAPServer
39 {
40 return $this->server;
41 }
42
46 public function doAuthentication(ilAuthStatus $status): bool
47 {
48 try {
49 // bind
50 $query = new ilLDAPQuery($this->getServer());
51 $query->bind();
52 } catch (ilLDAPQueryException $e) {
53 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
54 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
55 return false;
56 }
57 try {
58 // Read user data, which does ensure a sucessful authentication.
59 $users = $query->fetchUser(
60 $this->getCredentials()->getUsername()
61 );
62
63 if (!$users) {
64 $this->handleAuthenticationFail($status, 'err_wrong_login');
65 return false;
66 }
67 if (!trim($this->getCredentials()->getPassword())) {
68 $this->handleAuthenticationFail($status, 'err_wrong_login');
69 return false;
70 }
71 if (!array_key_exists($this->changeKeyCase($this->getCredentials()->getUsername()), $users)) {
72 $this->getLogger()->warning('Cannot find user: ' . $this->changeKeyCase($this->getCredentials()->getUsername()));
73 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
74 return false;
75 }
76
77 // check group membership
78 if (!$query->checkGroupMembership(
79 $this->getCredentials()->getUsername(),
80 $users[$this->changeKeyCase($this->getCredentials()->getUsername())]
81 )) {
82 $this->handleAuthenticationFail($status, 'err_wrong_login');
83 return false;
84 }
85 } catch (ilLDAPQueryException $e) {
86 $this->getLogger()->error('Cannot fetch LDAP user data... ' . $e->getMessage());
87 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
88 return false;
89 }
90 try {
91 // now bind with login credentials
92 $query->bind(
94 $users[$this->changeKeyCase($this->getCredentials()->getUsername())]['dn'],
95 $this->getCredentials()->getPassword()
96 );
97 } catch (ilLDAPQueryException $e) {
98 $this->handleAuthenticationFail($status, 'err_wrong_login');
99 return false;
100 }
101
102 // authentication success update profile
103 return $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
104 }
105
109 protected function updateAccount(ilAuthStatus $status, array $user): bool
110 {
111 $user = array_change_key_case($user, CASE_LOWER);
112 $this->getLogger()->dump($user, ilLogLevel::DEBUG);
113
114 $sync = new ilLDAPUserSynchronisation(
115 'ldap_' . $this->getServer()->getServerId(),
116 $this->getServer()->getServerId()
117 );
118 $sync->setExternalAccount($this->getCredentials()->getUsername());
119 $sync->setUserData($user);
120 $sync->forceCreation($this->force_new_account);
121
122 try {
123 $internal_account = $sync->sync();
124 $this->getLogger()->debug('Internal account: ' . $internal_account);
125 } catch (UnexpectedValueException $e) {
126 $this->getLogger()->info('Login failed with message: ' . $e->getMessage());
127 $this->handleAuthenticationFail($status, 'err_wrong_login');
128 return false;
130 $this->handleAuthenticationFail($status, 'err_auth_ldap_failed');
131 return false;
133 // No syncronisation allowed => create Error
134 $this->getLogger()->info('Login failed with message: ' . $e->getMessage());
135 $this->handleAuthenticationFail($status, 'err_auth_ldap_no_ilias_user');
136 return false;
138 // Account migration required
139 $this->setExternalAccountName($this->getCredentials()->getUsername());
140 $this->getLogger()->info('Authentication failed: account migration required for external account: ' . $this->getCredentials()->getUsername());
142 return false;
143 }
145 $status->setAuthenticatedUserId(ilObjUser::_lookupId($internal_account));
146 return true;
147 }
148
149 protected function initServer(int $a_server_id): void
150 {
151 $this->server = new ilLDAPServer($a_server_id);
152 $this->server->doConnectionCheck(true);
153 }
154
158 public function createNewAccount(ilAuthStatus $status): void
159 {
160 $this->force_new_account = true;
161
162 try {
163 $query = new ilLDAPQuery($this->getServer());
164 $query->bind();
165 } catch (ilLDAPQueryException $e) {
166 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
167 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
168 return;
169 }
170 try {
171 // fetch user
172 $users = $query->fetchUser(
173 $this->getCredentials()->getUsername()
174 );
175 if (!$users) {
176 $this->handleAuthenticationFail($status, 'err_wrong_login');
177 return;
178 }
179 if (!array_key_exists($this->changeKeyCase($this->getCredentials()->getUsername()), $users)) {
180 $this->handleAuthenticationFail($status, 'err_wrong_login');
181 return;
182 }
183 } catch (ilLDAPQueryException $e) {
184 $this->getLogger()->error('Cannot fetch LDAP user data... ' . $e->getMessage());
185 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
186 return;
187 }
188
189 // authentication success update profile
190 $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
191 }
192
196 public function migrateAccount(ilAuthStatus $status): void
197 {
198 $this->force_new_account = true;
199
200 try {
201 $query = new ilLDAPQuery($this->getServer());
202 $query->bind();
203 } catch (ilLDAPQueryException $e) {
204 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
205 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
206 return;
207 }
208
209 $users = $query->fetchUser($this->getCredentials()->getUsername());
210 $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
211 }
212
216 public function getTriggerAuthMode(): string
217 {
218 return ilAuthUtils::AUTH_LDAP . '_' . $this->getServer()->getServerId();
219 }
220
224 public function getUserAuthModeName(): string
225 {
226 return 'ldap_' . $this->getServer()->getServerId();
227 }
228
232 public function getExternalAccountName(): string
233 {
235 }
236
237 public function setExternalAccountName(string $a_name): void
238 {
239 $this->migration_account = $a_name;
240 }
241
246 protected function changeKeyCase(string $a_string)
247 {
248 return array_key_first(array_change_key_case([$a_string => $a_string]));
249 }
250}
updateAccount(ilAuthStatus $status, array $user)
Update Account.
doAuthentication(ilAuthStatus $status)
@inheritDoc
changeKeyCase(string $a_string)
Change case similar to array_change_key_case, to avoid further encoding problems.
setExternalAccountName(string $a_name)
__construct(ilAuthCredentials $credentials, int $a_server_id=0)
migrateAccount(ilAuthStatus $status)
@inheritDoc
createNewAccount(ilAuthStatus $status)
@inheritDoc
handleAuthenticationFail(ilAuthStatus $status, string $a_reason)
ilAuthCredentials $credentials
const int STATUS_ACCOUNT_MIGRATION_REQUIRED
setAuthenticatedUserId(int $a_id)
setStatus(int $a_status)
Set auth status.
const int STATUS_AUTHENTICATED
const int AUTH_LDAP
Thrown in case of failed synchronisation settings.
Synchronization of user accounts used in auth container ldap, ,...
static _lookupId(string|array $a_user_str)
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc