LDAP创建用户后认证失败,咨询正确的密码加密方式
问题根源
你的代码存在三个核心问题,导致密码设置失败且登录提示无效凭据:
- 错误的密码属性:Active Directory(AD)不使用
userPassword存储密码,必须用unicodePwd属性。 - unicodePwd格式不符合要求:AD要求该属性值必须是被双引号包裹的密码,再转成UTF-16LE编码,你注释的代码缺少双引号,无法被AD识别。
- 未使用加密连接:AD禁止在明文LDAP连接(389端口)下修改密码,必须用LDAPS(636端口)或StartTLS加密连接。
- userAccountControl设置冲突:你设置的
66656包含PASSWD_NOTREQD(1024)标志,这会让账户无需密码即可登录,测试时输入密码反而会被判定为无效。
修复方案
1. 切换到加密连接
使用LDAPS协议连接,修改地址和端口:
$ds = 'ldaps://192.168.1.10'; $portldap = 636;
如果需要用StartTLS(保持389端口),在绑定前添加:
ldap_start_tls($ldap_connection);
2. 正确生成unicodePwd
替换密码修改逻辑,确保密码被双引号包裹并转成UTF-16LE:
// 生成符合AD要求的unicodePwd值 $password = '"' . $ldap_password_user . '"'; $addPrecord["unicodePwd"] = iconv('UTF-8', 'UTF-16LE', $password); // 修正userAccountControl为普通账户(要求必须有密码) $addPrecord["userAccountControl"][0] = "512";
3. 调整userAccountControl值
常用的合法值:
512:普通账户(NORMAL_ACCOUNT),强制用户必须使用密码登录66048:普通账户 + 密码永不过期(NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD)- 禁止添加
1024(PASSWD_NOTREQD),否则账户无需密码即可登录
完整修正后的代码
$ds = 'ldaps://192.168.1.10'; $portldap = 636; $ldap_username = 'CN=Administrador,CN=Users,DC=Local,DC=com'; $ldap_password = 'rootadm1'; $ldap_password_user = $ldap_password; $ldap_connection = ldap_connect($ds, $portldap); if($ldap_connection ){ ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version'); ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); // 测试环境可临时关闭证书验证,生产环境需配置有效证书 ldap_set_option($ldap_connection, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER); $r = ldap_bind($ldap_connection, $ldap_username, $ldap_password); if($r === TRUE){ $CN = htmlspecialchars($_POST["cn"]); $ldaprecord['cn'] = $CN; $ldaprecord['sAMAccountName'] = $_POST["sAMAccountName"]; $ldaprecord['userPrincipalName'] = $_POST["userprincipalname"]; $ldaprecord["objectClass"] = ["top", "person", "organizationalPerson", "user"]; $ldaprecord['description']= $_POST["description"]; // 初始设置为普通账户 $ldaprecord["userAccountControl"][0] = "512"; $ldap_new = 'CN='.$CN.',CN=Users,DC=Local,DC=com'; $result = ldap_add($ldap_connection, $ldap_new, $ldaprecord); if($result) { // 正确设置用户密码 $password = '"' . $ldap_password_user . '"'; $addPrecord["unicodePwd"] = iconv('UTF-8', 'UTF-16LE', $password); // 可选:设置密码永不过期 // $addPrecord["userAccountControl"][0] = "66048"; $add_record= ldap_modify($ldap_connection, $ldap_new, $addPrecord); if($add_record){ ldap_close($ldap_connection); return $result; } else { echo "LDAP Error: ".ldap_error($ldap_connection)."\n"; exit; } } else { echo "LDAP Error: ".ldap_error($ldap_connection)."\n"; exit; } } } else { echo "cannot connect to LDAP server at $ds."; }
额外注意事项
- 生产环境必须配置有效的LDAPS证书,禁止关闭证书验证
- 绑定的管理员账号需拥有修改目标用户密码的权限
- 密码必须符合AD的密码策略(长度、复杂度、历史限制等),否则修改会失败
内容的提问来源于stack exchange,提问作者jesus
相关产品推荐
相关产品推荐

