繁体   English   中英

php_ldap - 尝试 StartTLS 但失败时继续

[英]php_ldap - Try StartTLS but keep going when it fails

由于运行相同代码的各种客户环境,我正在尝试使用 PHP 构建一个 LDAP 身份验证系统,该系统可能在 3 种模式下工作:

  1. 根本不要使用 StartTLS(当 LDAP 服务器更喜欢 LDAPS 时)
  2. 尝试 StartTLS 但如果 LDAP 服务器拒绝 TLS,则继续不安全
  3. 如果 LDAP 服务器拒绝 TLS,请尝试 StartTLS 并中止身份验证

这是代码的简化版本:

// 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始终返回 false),对于$configStartTls的每个值

  1. ldap_bind成功 - OK
  2. ldap_bind失败- KO
  3. 未尝试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_connectldap_bind之间重新应用 LDAP 选项,这意味着我可能在第二次尝试时使用了 LDAP v2,这就是服务器拒绝它的原因。

这是完整的工作代码。 它包括一个不支持 TLS 的免费公共 LDAP 服务器的 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM