rgergo67/openldap

Laravel 包,用于管理 OpenLDAP 中的用户和组

2.0.1 2021-04-14 13:27 UTC

This package is auto-updated.

Last update: 2024-09-14 21:36:12 UTC


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_dnadmin_password,这些用于连接到 openldap,应在您的 .env 文件中定义。

dn

配置中还有 4 个其他 dn 键:base_user_dn:如果您有多个用户子树(如我们一样)(学生、员工),则这些应该位于 ou=people 节点下面,因此如果您正在寻找具有 email=ratting.gergo@uni-pannon.hu 的用户,您不必过滤两次(一次在学生树中,一次在员工树中)。base_student_dnbase_employee_dn:我们需要知道它们在哪里,以便当我们在创建新员工时,我们可以将其放置在正确的位置 bsae_group_dn:您的组所在的节点。

我们使用 POSIX 组。基本组 dn 是 ou=sys,dc=example,dc=com,但您可以使用任何内容。在此节点下面是 ou=joomlaou=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"
  ]
]