rgergo67 / openldap
Laravel 包,用于管理 OpenLDAP 中的用户和组
README
请随意fork它并按需修改,但不要在生产环境中使用。版本编号不遵循任何约定,此版本仅用于测试目的。
Openldap-laravel
使用此包,您可以向 OpenLdap 添加用户,编辑和删除他们,管理他们的属性并将他们添加到 POSIX 组。该包用于具有特定需求的特定项目,请随意修改。
安装
使用 composer 安装
composer require rgergo67/openldap
运行 php artisan vendor:publish,这将把 openldap.php 配置文件复制到配置目录。将以下行添加到 config/app.php 提供者数组中
/*
* Package Service Providers...
*/
\Rgergo67\Openldap\OpenldapServiceProvider::class,
基本用法
要使用此包,您的用户模型需要两个东西。
DN 属性
首先它必须有一个 dn 属性,您可以在虚拟中创建或从 mysql 字段中获取它。在我们的 User.php 模型中它看起来像这样
/** * Gets the dn attribute. * * @return string The dn attribute. */ public function getDnAttribute(){ $baseUserDn = $this->isStudent() ? config('openldap.base_student_dn') : config('openldap.base_employee_dn'); return config('openldap.login_attribute') . "=" . $this->uid . "," . $baseUserDn; }
我们存储员工和学生在不同的组织单位中,因此我们需要能够决定给定的用户属于哪个单位。(学生具有 6 个字符长度的 uid,员工具有 10 个字符长度的 uid)。此 dn 属性的一个示例值是 cn=rgergo6,ou=student,ou=people,dc=example,dc=com
ldap-format 属性
第二件事是一个名为 ldap-attribute 的数组。这个数组将 mysql 字段转换为 ldap 字段。例如
/** * Gets the ldap format attribute. * * @return array The ldap format attribute. */ public function getLdapFormatAttribute(){ return [ "objectClass" => config('openldap.user_object_class'), 'cn' => $this->name, 'sn' => $this->name, 'mail' => $this->email, 'gidNumber' => 1, 'homeDirectory' => '/home/' . $this->username, 'uid' => $this->uid, 'uidNumber' => 67 ]; }
如果您执行 addUser($user);,该包将使用此数组在 ldap 中创建一个用户。
对象类
objectClass 属性告诉 ldap 用户是什么类型的对象(这将指定您可以给它哪些属性)。您可以在配置文件中编辑此值,我们使用此
'user_object_class' => [ "top", "person", "eduPerson", "posixAccount", "inetOrgPerson", "radiusprofile", "shadowAccount", "schacContactLocation", "organizationalPerson", "schacLinkageIdentifiers" , ],
在大多数情况下,top, person, posixAccount, InetorgPerson 就足够了,但我们需要其他一些属性来满足我们的项目需求。
配置
在配置文件中,您可以看到 admin_dn 和 admin_password,这些用于连接到 openldap,应在您的 .env 文件中定义。
dn
配置中还有 4 个其他 dn 键:base_user_dn:如果您有多个用户子树(如我们一样)(学生、员工),则这些应该位于 ou=people 节点下面,因此如果您正在寻找具有 email=ratting.gergo@uni-pannon.hu 的用户,您不必过滤两次(一次在学生树中,一次在员工树中)。base_student_dn 和 base_employee_dn:我们需要知道它们在哪里,以便当我们在创建新员工时,我们可以将其放置在正确的位置 bsae_group_dn:您的组所在的节点。
组
我们使用 POSIX 组。基本组 dn 是 ou=sys,dc=example,dc=com,但您可以使用任何内容。在此节点下面是 ou=joomla 和 ou=moodle,用于将类似的系统分组在一起。如果我们创建一个新的 joomla 网站,如 hr.example.com,我们为它创建一个新的组织单位 ou=hr.example.com,ou=joomla,ou=sys,dc=example,dc=com,并在下面为每个 joomla 组(编辑器、注册用户、管理员)创建一个 POSIX 组:cn=editor,ou=hr.example.com,ou=joomla,ou=sys,dc=example,dc=com
用法
//create a new openldap object $openldap = new Openldap(); //find a user in your mysql database $user = User::findOrFail(1); // Adding new user, where $user should have dn and ldap_format virtual fields $openldap->addUser($user); // Find this newly added user by its uid in ldap $openldap->findUserByUid($user->uid); // To add new password without checking the old one $openldap->newPassword($user, "secret"); // To replace the old password, and checking if it's correct $openldap->replacePassword($user, "oldSecret", "newSecret"); dump($group->dn); //"cn=editor,ou=hr.example.com,ou=joomla,ou=sys,dc=example,dc=com"; dump($group->ldap_format); /** * [ * "objectClass" => config('openldap.group_object_class'), * 'cn' => "editor" * ] */ //Adding a group $openldap->addRecord($group->dn, $group->ldap_format); // Adding user to a group $openldap->addUserToGroup($user, $group_dn); // Add attribute to dn. $record should be in format ['attribute' => 'value'] $record['mail' => 'rgerg67o@example.com'] $openldap->addAttribute($dn, $record); /* List the users groups. It returns an array of group dns like this: [ 0 => [ 'dn' => 'cn=group1,dc=example,dc=com' ], 1 => [ 'dn' => 'cn=group2,dc=example,dc=com' ] ] */ $openldap->$openldap->getUserGroups($user); // Delete user from group $openldap->deleteUserFromGroup($user, $group_dn); // Delete user from all groups $openldap->deleteUserFromAllGroups($user);
更新用户
如果您想更新一个用户,首先检查其 uid(或 dn 中的一部分)是否已更改。如果是,首先重命名它,然后再更新。重命名参数的第三个参数仅用于将记录移动到其他地方。请注意,第二个参数是 RDN,而不是完整的 DN。
if($user->isDirty('uid')){
if(!$openldap->rename($user->oldDn, 'uid='.$user->uid, null))
return false;
}
$openldap->updateUser($user);
还有一点:如果您要重命名某个东西,第一个参数应该是旧DN。例如,如果您挂钩到用户更新事件,$user对象的$>uid字段(DN的一部分)将包含更新的uid(如果您修改了它)。要获取旧DN,请使用Laravel的$user->getOriginal()函数。
public function getOldDnAttribute()
{
return "uid={$this->getOriginal('uid')},{$this->baseEmployeeDn}";
}
### 同步组 有时候您只需要确保用户组已全部同步。此功能将删除用户的所有组,并再次添加它们。
$openldap->syncUserGroups($user);
### 保存用户时同步组 将钩子挂钩到用户保存事件,并在那里运行组同步。我们有一系列带有组名的复选框,我们可以使用request('groups')检索。
// if all groups were deleted, return
if(!request('groups'))
return true;
$this->openldap->deleteUserFromAllGroups($user);
foreach(request('groups') as $groupId){
$group = Group::findOrFail($groupId);
$this->openldap->addUserToGroup($user, $group->dn);
}
### 清理数组 如果您从LDAP获取搜索结果,它具有丑陋的格式,很难处理。如果您使用cleanUpEntry($entry)函数,它将返回一个美丽的清理后的PHP数组。归功于Chl
简单搜索结果的示例
dump($this->openldap->search("ou=phonebook,ou=dev,dc=uni-pannon,dc=hu", "uid=ratting.gergo.mik-math"));
array:2 [▼
"count" => 1
0 => array:18 [▼
"objectclass" => array:5 [▼
"count" => 4
0 => "top"
1 => "person"
2 => "organizationalPerson"
3 => "inetOrgPerson"
]
0 => "objectclass"
"sn" => array:2 [▼
"count" => 1
0 => "Ratting"
]
1 => "sn"
"cn" => array:2 [▼
"count" => 1
0 => "Ratting Gergely"
]
2 => "cn"
"displayname" => array:2 [▼
"count" => 1
0 => "Ratting Gergely"
]
3 => "displayname"
"telephonenumber" => array:2 [▼
"count" => 1
0 => "4835"
]
4 => "telephonenumber"
"ou" => array:3 [▼
"count" => 2
0 => "MIK"
1 => "MIK-MATH"
]
5 => "ou"
"roomnumber" => array:2 [▼
"count" => 1
0 => "B211"
]
6 => "roomnumber"
"uid" => array:2 [▼
"count" => 1
0 => "ratting.gergo.mik-math"
]
7 => "uid"
"count" => 8
"dn" => "uid=ratting.gergo.mik-math,ou=phonebook,ou=dev,dc=uni-pannon,dc=hu"
]
]
如果我们清理结果
dump($this->openldap->cleanUpEntry(
$this->openldap->search("ou=phonebook,ou=dev,dc=uni-pannon,dc=hu", "uid=ratting.gergo.mik-math")
));
array:1 [▼
"uid=ratting.gergo.mik-math,ou=phonebook,ou=dev,dc=uni-pannon,dc=hu" => array:8 [▼
"objectclass" => array:4 [▼
0 => "top"
1 => "person"
2 => "organizationalPerson"
3 => "inetOrgPerson"
]
"sn" => "Ratting"
"cn" => "Ratting Gergely"
"displayname" => "Ratting Gergely"
"telephonenumber" => "4835"
"ou" => array:2 [▼
0 => "MIK"
1 => "MIK-MATH"
]
"roomnumber" => "B211"
"uid" => "ratting.gergo.mik-math"
]
]