简体   繁体   English

php_ldap - 尝试 StartTLS 但失败时继续

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

Because of various customers environments running the same code, I'm trying to build an LDAP authentification system with PHP that may work in 3 modes:由于运行相同代码的各种客户环境,我正在尝试使用 PHP 构建一个 LDAP 身份验证系统,该系统可能在 3 种模式下工作:

  1. Do not use StartTLS at all (for when the LDAP server prefers LDAPS instead)根本不要使用 StartTLS(当 LDAP 服务器更喜欢 LDAPS 时)
  2. Try StartTLS but keep going unsecured if the LDAP server refuses TLS尝试 StartTLS 但如果 LDAP 服务器拒绝 TLS,则继续不安全
  3. Try StartTLS and abort authentication if the LDAP server refuses TLS如果 LDAP 服务器拒绝 TLS,请尝试 StartTLS 并中止身份验证

Here is a simplified version of the code:这是代码的简化版本:

// 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
}

Here are the results with a LDAP server that does not support TLS ( ldap_start_tls always returns false), for each value of $configStartTls以下是不支持 TLS 的 LDAP 服务器的结果( ldap_start_tls始终返回 false),对于$configStartTls的每个值

  1. ldap_bind is successful - OK ldap_bind成功 - OK
  2. ldap_bind fails - KO ldap_bind失败- KO
  3. ldap_bind is not attempted - OK未尝试ldap_bind - OK

In case 2:情况 2:

  • ldap_start_tls logs "Connect error" with error code 11 ldap_start_tls记录“连接错误”,错误代码为 11
  • ldap_bind logs "Can't contact LDAP server" with error -1 ldap_bind记录“无法联系 LDAP 服务器”,错误为 -1

I don't understand why ldap_bind fails in case 2. It's as if using ldap_start_tls made the use of TLS mandatory.我不明白为什么ldap_bind在案例 2 中失败。就好像使用ldap_start_tls强制使用 TLS 一样。 I expected it would be possible to keep communicating with the LDAP server after a failure, in a non-secured way.我希望在发生故障后以非安全方式继续与 LDAP 服务器通信。

Do I have to cancel the use of StartTLS, after a failure, to implement option 2?是否必须在失败后取消使用 StartTLS 才能实施选项 2? How would I do this?我该怎么做?

I simply needed to do ldap_connect again to start over without using StartTLS.我只需要再次执行ldap_connect即可重新开始,而无需使用 StartTLS。 I had tried that and failed, but only because I forgot to re-apply the LDAP options between ldap_connect and ldap_bind , which means I was probably using LDAP v2 on the second attempt, and that's why the server refused it.我曾尝试过但失败了,但这只是因为我忘记在ldap_connectldap_bind之间重新应用 LDAP 选项,这意味着我可能在第二次尝试时使用了 LDAP v2,这就是服务器拒绝它的原因。

Here is full working code.这是完整的工作代码。 It includes URI, BindDN and password of a free public LDAP server with no TLS support, so anyone who would face the same problem can try the code themselves and tinker with it.它包括一个不支持 TLS 的免费公共 LDAP 服务器的 URI、BindDN 和密码,因此任何遇到同样问题的人都可以自己尝试代码并修改它。 Just change the value of $startTlsMode to any of the constants to try other modes.只需将$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