first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Auth;
|
||||
|
||||
class LdapService
|
||||
{
|
||||
public function authenticate(string $login, string $password): array|false
|
||||
{
|
||||
$config = require __DIR__ . '/../../../config/ldap.php';
|
||||
|
||||
$host = $config['host'];
|
||||
$port = $config['port'];
|
||||
$baseDn = $config['base_dn'];
|
||||
$domain = $config['domain'];
|
||||
$adminGroupName = $config['admin_group_name'] ?? 'ИТ-Отдел';
|
||||
|
||||
$connection = ldap_connect("ldap://{$host}:{$port}");
|
||||
|
||||
if (!$connection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
$bindRdn = $login . '@' . $domain;
|
||||
|
||||
$bind = @ldap_bind($connection, $bindRdn, $password);
|
||||
|
||||
if (!$bind) {
|
||||
ldap_unbind($connection);
|
||||
return false;
|
||||
}
|
||||
|
||||
$filter = sprintf('(sAMAccountName=%s)', ldap_escape($login, '', LDAP_ESCAPE_FILTER));
|
||||
$attributes = ['cn', 'displayName', 'mail', 'sAMAccountName', 'memberOf'];
|
||||
|
||||
$search = @ldap_search($connection, $baseDn, $filter, $attributes);
|
||||
|
||||
if (!$search) {
|
||||
ldap_unbind($connection);
|
||||
return [
|
||||
'login' => $login,
|
||||
'display_name' => $login,
|
||||
'email' => null,
|
||||
'groups' => [],
|
||||
'is_admin' => false,
|
||||
];
|
||||
}
|
||||
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
ldap_unbind($connection);
|
||||
|
||||
if (($entries['count'] ?? 0) < 1) {
|
||||
return [
|
||||
'login' => $login,
|
||||
'display_name' => $login,
|
||||
'email' => null,
|
||||
'groups' => [],
|
||||
'is_admin' => false,
|
||||
];
|
||||
}
|
||||
|
||||
$entry = $entries[0];
|
||||
|
||||
$groups = [];
|
||||
if (!empty($entry['memberof']) && is_array($entry['memberof'])) {
|
||||
for ($i = 0; $i < ($entry['memberof']['count'] ?? 0); $i++) {
|
||||
$dn = $entry['memberof'][$i];
|
||||
if (preg_match('/CN=([^,]+)/u', $dn, $matches)) {
|
||||
$groups[] = $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$isAdmin = false;
|
||||
|
||||
foreach ($groups as $group) {
|
||||
if (mb_strtolower(trim($group)) === mb_strtolower(trim($adminGroupName))) {
|
||||
$isAdmin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'login' => $entry['samaccountname'][0] ?? $login,
|
||||
'display_name' => $entry['displayname'][0] ?? $entry['cn'][0] ?? $login,
|
||||
'email' => $entry['mail'][0] ?? null,
|
||||
'groups' => $groups,
|
||||
'is_admin' => $isAdmin,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user