php_ldap - 尝试 StartTLS 但在失败时继续
php_ldap - Try StartTLS but keep going when it fails
由于不同的客户环境 运行 相同的代码,我正在尝试使用 PHP 构建一个 LDAP 身份验证系统,它可以在 3 种模式下工作:
- 根本不使用 StartTLS(当 LDAP 服务器更喜欢 LDAPS 时)
- 尝试 StartTLS,但如果 LDAP 服务器拒绝 TLS,则继续不安全
- 如果 LDAP 服务器拒绝 TLS,请尝试启动 TLS 并中止身份验证
这里是代码的简化版本:
// ldap_connect is successful and returns $ldap
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER); // I tried ALLOW and TRY as well and got the same results
// $configStartTls contains 1, 2 or 3 (see options above)
if ($configStartTls > 1) {
$tlsOk = ldap_start_tls($ldap) || ($configStartTls === 2);
} else {
$tlsOk = true;
}
if ($tlsOk) {
// ldap_bind here
}
以下是不支持 TLS 的 LDAP 服务器的结果(ldap_start_tls
总是 returns 错误),对于 $configStartTls
的每个值
ldap_bind
成功 - OK
ldap_bind
失败 - KO
ldap_bind
未尝试 - OK
案例2:
ldap_start_tls
记录“连接错误”,错误代码为 11
ldap_bind
记录“无法联系 LDAP 服务器”,错误为 -1
我不明白为什么 ldap_bind
在情况 2 中失败。就好像使用 ldap_start_tls
强制使用 TLS 一样。我希望在失败后能够以不安全的方式继续与 LDAP 服务器通信。
我是否必须在失败后取消使用 StartTLS 才能实施选项 2?我该怎么做?
我只需要再次执行 ldap_connect
即可在不使用 StartTLS 的情况下重新开始。我曾尝试过但失败了,但这只是因为我忘记在 ldap_connect
和 ldap_bind
之间重新应用 LDAP 选项,这意味着我可能在第二次尝试时使用了 LDAP v2,这就是为什么服务器拒绝了。
这是完整的工作代码。它包括不支持 TLS 的 free public LDAP server 的 URI、BindDN 和密码,因此任何遇到相同问题的人都可以自己尝试代码并修改它。只需将 $startTlsMode
的值更改为任何常量即可尝试其他模式。
const TLS_NO = 1;
const TLS_OPTIONAL = 2;
const TLS_MANDATORY = 3;
$startTlsMode = TLS_OPTIONAL;
$ldap = connectAndSetOptions();
if ($startTlsMode === TLS_OPTIONAL || $startTlsMode === TLS_MANDATORY) {
$tlsOk = ldap_start_tls($ldap);
} else {
$tlsOk = true;
}
// TLS optional and StartTLS failed, start over without using StartTLS
if ($startTlsMode === TLS_OPTIONAL && !$tlsOk) {
$ldap = connectAndSetOptions();
$tlsOk = true;
}
// TLS successful or not necessary, proceed with binding
if ($tlsOk) {
$bindOK = ldap_bind($ldap, 'cn=read-only-admin,dc=example,dc=com', 'password');
echo $bindOK ? 'Bind successful' : 'Bind failed';
} else {
echo 'No bind attempt';
}
function connectAndSetOptions() {
$ldap = ldap_connect('ldap://ldap.forumsys.com:389');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_TRY);
return $ldap;
}
由于不同的客户环境 运行 相同的代码,我正在尝试使用 PHP 构建一个 LDAP 身份验证系统,它可以在 3 种模式下工作:
- 根本不使用 StartTLS(当 LDAP 服务器更喜欢 LDAPS 时)
- 尝试 StartTLS,但如果 LDAP 服务器拒绝 TLS,则继续不安全
- 如果 LDAP 服务器拒绝 TLS,请尝试启动 TLS 并中止身份验证
这里是代码的简化版本:
// ldap_connect is successful and returns $ldap
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER); // I tried ALLOW and TRY as well and got the same results
// $configStartTls contains 1, 2 or 3 (see options above)
if ($configStartTls > 1) {
$tlsOk = ldap_start_tls($ldap) || ($configStartTls === 2);
} else {
$tlsOk = true;
}
if ($tlsOk) {
// ldap_bind here
}
以下是不支持 TLS 的 LDAP 服务器的结果(ldap_start_tls
总是 returns 错误),对于 $configStartTls
ldap_bind
成功 - OKldap_bind
失败 - KOldap_bind
未尝试 - OK
案例2:
ldap_start_tls
记录“连接错误”,错误代码为 11ldap_bind
记录“无法联系 LDAP 服务器”,错误为 -1
我不明白为什么 ldap_bind
在情况 2 中失败。就好像使用 ldap_start_tls
强制使用 TLS 一样。我希望在失败后能够以不安全的方式继续与 LDAP 服务器通信。
我是否必须在失败后取消使用 StartTLS 才能实施选项 2?我该怎么做?
我只需要再次执行 ldap_connect
即可在不使用 StartTLS 的情况下重新开始。我曾尝试过但失败了,但这只是因为我忘记在 ldap_connect
和 ldap_bind
之间重新应用 LDAP 选项,这意味着我可能在第二次尝试时使用了 LDAP v2,这就是为什么服务器拒绝了。
这是完整的工作代码。它包括不支持 TLS 的 free public LDAP server 的 URI、BindDN 和密码,因此任何遇到相同问题的人都可以自己尝试代码并修改它。只需将 $startTlsMode
的值更改为任何常量即可尝试其他模式。
const TLS_NO = 1;
const TLS_OPTIONAL = 2;
const TLS_MANDATORY = 3;
$startTlsMode = TLS_OPTIONAL;
$ldap = connectAndSetOptions();
if ($startTlsMode === TLS_OPTIONAL || $startTlsMode === TLS_MANDATORY) {
$tlsOk = ldap_start_tls($ldap);
} else {
$tlsOk = true;
}
// TLS optional and StartTLS failed, start over without using StartTLS
if ($startTlsMode === TLS_OPTIONAL && !$tlsOk) {
$ldap = connectAndSetOptions();
$tlsOk = true;
}
// TLS successful or not necessary, proceed with binding
if ($tlsOk) {
$bindOK = ldap_bind($ldap, 'cn=read-only-admin,dc=example,dc=com', 'password');
echo $bindOK ? 'Bind successful' : 'Bind failed';
} else {
echo 'No bind attempt';
}
function connectAndSetOptions() {
$ldap = ldap_connect('ldap://ldap.forumsys.com:389');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_TRY);
return $ldap;
}