OpenLDAP之Laravel

2020年04月17日 317点热度 1人点赞 0条评论

前言

在Laravel中进行OpenLDAP认证,因为需要写代码,一写代码就有个人思想,这里仅仅是我个人的一种认证方式,如果需要使用还得考虑自身的业务场景。

依赖

这里我使用的是大名鼎鼎的symfony家出的ldap库,地址:symfony/ldap 。正常创建一个Laravel项目,然后添加依赖,然后写代码。

代码

.env中配置的文件如下,这里配置的是我个人代码,包装了一下,主要展示一下登陆的账户名和密码的样子。
LDAP_USERNAME=cn=admin,dc=9x6,dc=cn
LDAP_PASSWORD=admin
ldap.php的config文件,此处也是我个人包装的代码,方便后续更改管理员密码时及时便捷的更改。
return [
    'host'       => env('LDAP_HOST', '127.0.0.1'),
    'port'       => env('LDAP_PORT', 389),
    'version'    => env('LDAP_VERSION', 3),
    'encryption' => env('LDAP_ENCRYPTION', 'none'),
    'username'   => env('LDAP_USERNAME', null),
    'password'   => env('LDAP_PASSWORD', null),
];
下面是登陆逻辑核心的相关代码:
/**
 * 登陆检测方法
 * 
 * @author www.sollyu.com
 * @param AuthLoginRequest $request
 * @return AuthLoginResource
 */
public function login(AuthLoginRequest $request)
{
    // 创建一个ldap链接,此处ldap()等同于try里语句
    // 此处使用的管理员账户进行链接,方便查询登陆的账户是否存在
    $ldapUserList = ldap()->query('ou=users,dc=9x6,dc=cn', sprintf('(&(objectClass=mailAccount)(uid=%s))', $request['email']), ['maxItems' => 1])->execute();

    // 检查出使用邮件的不是一个或者没有此邮箱,禁止登陆。
    if ($ldapUserList->count() !== 1)
        throw new HttpException($statusCode = FoundationResponse::HTTP_INTERNAL_SERVER_ERROR, $message = '无效账户或密码');

    // 尝试进行登陆
    try {
        // 新建一个ldap链接,用于登陆账户密码验证
        // 此处方法和上面的ldap()方法一样,只不过上面有绑定管理员账户
        $ldap = Ldap::create($adapter = 'ext_ldap', $config = [
            'host'       => config($key = 'ldap.host'),
            'port'       => config($key = 'ldap.port'),
            'version'    => config($key = 'ldap.version'),
            'encryption' => config($key = 'ldap.encryption'),
        ]);

        // 绑定需要登陆账户dn和密码
        // 如果这里通过说明密码正确,否则就会抛出异常
        // dn的事例:uid=xxxx@sollyu.com,ou=users,dc=9x6,dc=cn
        $ldap->bind($ldapUserList[0]->getDn(), $request['password']);

        // 获取账户的邮箱地址,返回的是数组
        $ldapUserMail = $ldapUserList[0]->getAttribute('mail');

        // 没有配置邮箱,不允许进行登陆
        if (count($ldapUserMail) === 0)
            throw new HttpException($statusCode = FoundationResponse::HTTP_INTERNAL_SERVER_ERROR, $message = '账户未配置邮箱');

        // 检查账户是否在此系统中是否存在,不存在就新建一个数据库对象
        // 此处主要是生成JwtToken,需要一个数据库对象
        $user = self::FindOrCreateUser($request['email']);

        // 进行登陆操作
        auth_api()->login($user);

        // 返回登陆token信息等
        return new AuthLoginResource($user);
    } catch (Exception $e) {
        // 此处的异常主要来自 密码登陆失败
        // 没有做其他异常情况下处理
        throw new HttpException($statusCode = FoundationResponse::HTTP_NOT_FOUND, $message = '无效账户或密码');
    }
}

测试

使用Laravel的测试
class AuthTest extends TestCase
{
    use RefreshDatabase;

    /**
     * 此处需要一个OpenLDAP中存在的账户
     */
    public function testLoginSuccess()
    {
        $this->refreshDatabase();
        $response = $this->postJson(route('api.v1.auth.login'), ['email' => 'sollyu@qq.com', 'password' => 'sa']);
        $response->assertSuccessful();
    }
}

结束

以上就是OpenLDAP对接Laravel的登陆方式

Sollyu

保持饥渴的专注,追求最佳的品质

文章评论