我在lumen项目(Laravel 6.2)中有一个过程,其中通过LDAP识别用户。代码看起来像这样:
<?php
namespace App\Http\Helpers;
// Currently unused
// use App\User;
// use Firebase\JWT\JWT;
use Illuminate\Support\Facades\Log;
class LDAP
{
private $connection, $password;
protected $domain, $username, $ldap_address, $ldap_port;
/**
* Constructs the ldap connector with data used for the connection and
* bind process.
*/
function __construct()
{
$this->domain = env("LDAP_DOMAIN");
$this->username = env("LDAP_USERNAME");
$this->password = env("LDAP_PASSWORD");
$this->ldap_address = env("LDAP_ADDRESS");
$this->ldap_port = env("LDAP_PORT");
}
/**
* Establishes a connection to the ldap server and saves it in
* @var Resource $connection.
*
* @return true
* On success
* @return false
* On failure
*/
private function connect()
{
$this->connection = ldap_connect($this->ldap_address, $this->ldap_port);
if($this->connection)
{
Log::info("Connection established");
ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($this->connection, $this->domain . "\\" . $this->username, $this->password);
if($bind)
{
Log::info("Bind valid");
return true;
}
else
{
Log::info("Bind failed");
return false;
}
}
else
{
Log::info("Connection failed");
return false;
}
}
private function disconnect()
{
ldap_unbind($this->connection);
}
/**
* Searches for a specific person in the LDAP-Directory and returns important
* data from this person which will be used later in the application.
*
* @param String $person
* The person to search for
* @return Array $result
* The persons data
*/
public function getUser($username, $password)
{
try
{
$is_connected = $this->connect();
if(!$is_connected)
{
$this->disconnect();
return false;
}
$dn = "OU=Benutzer,OU=sdfsfd,DC=sfdsfsf,DC=de";
$fields = "(|(samaccountname=*$username*))";
$search = ldap_search($this->connection, $dn, $fields);
$result = ldap_get_entries($this->connection, $search);
if($result)
{
$bind = ldap_bind($this->connection, $this->domain . "\\" . $username, $password);
if($bind && strlen($password) > 0)
{
return mb_convert_encoding($result, 'UTF-8');
}
else
{
return "Invalid credentials!";
}
}
else
{
return "User does not exist!";
}
}
catch(\Exception $e)
{
$errno = ldap_errno($this->connection);
if ($errno) {
$ret = array("ldap_error" => $errno, "message" => ldap_err2str($errno));
}else{
$ret = array("exception_code" => $e->getCode(), "message" => $e->getMessage());
}
return $ret;
}
finally
{
$this->disconnect();
}
}
}
[现在,在处理ldap_bind()
中的错误时,我们遇到了一些问题。流明无法评估ldap函数抛出的错误代码,因此我们必须捕获它们并通过ldap_errno
功能手动对其进行评估。
[让我感到困惑的是$this->connection
被传递给ldap_errno()
函数。为什么不是$bind
?毕竟,它的绑定失败了,而不是连接。 AFAIK ldap_connect()
甚至没有建立连接,而是验证凭据是否合理。
但是,它起作用^^但是为什么呢? ldap_errno发生了什么,将连接传递给它,而不是绑定?
因为ldap_connect
返回了标识“连接”的内部句柄。然后,ldap_errno
和ldap_error
返回有关该“连接”上最后一个错误的信息。
因此,当您在ldap_bind
之后调用它们(根据结果返回true
或false
时,您需要发生此连接,而不是绑定的结果。
请注意,“连接”并不一定意味着已经建立与服务器的连接。