【问题标题】:Foreign characters and LDAP. What encoding/charset does LDAP expect?外来字符和 LDAP。 LDAP 期望什么编码/字符集?
【发布时间】:2012-06-14 14:32:56
【问题描述】:

我正在解析 XML,使用 simplexml_load_string(),并使用其中的数据通过 LDAP 更新 Active Directory (AD) 对象。

示例 XML(简化):

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>Bìlbö Bággįnš</user>
    <user>Gãńdåłf Thê Gręât</user>
    <user>Śām Wīšë</user>
</users>

我首先运行ldap_search() 来查找单个用户,然后继续更改他们的属性。使用 LDAP 将上述值直接输入 AD 会导致出现一些非常混乱的字符。

例如:Bìlbö BággįnÅ¡

我尝试了以下功能,但无济于事:

utf8_encode($str);
utf8_decode($str);
iconv("UTF-8", "ISO-8859-1//TRANSLIT", $str);
iconv("UTF-8", "ASCII//TRANSLIT", $str);
iconv("UTF-8", "T.61", $str);

理想情况下,我不想进行任何这些字符串转换。 UTF-8应该没问题吧?!

我还注意到以下几点: 我已经打印出这些值,看看它们是如何产生的。在 CLI 中卷曲脚本将显示正确的字符,但 Web 浏览器显示与 AD 相同。

发生了什么事?我应该看别的东西吗,例如。网址编码? 我希望这归结为我的一个简单错误。

编辑: 我使用 AD admin GUI 输入了这些字符,看看它们会如何出现。我可以通过 LDAP 很好地阅读它们。在浏览器中显示正确的字符。通过 CLI 卷曲将显示问号而不是外来字符。将这些返回值之一传递到 mb_detect_encoding() 将返回 UTF-8。

我决定立即修改同一个对象,不写入新字符串,而只是反转现有值并保存对象。这很好用 - 我在 AD 中看到了正确的值(反转)。

  • 在 Mac OS X 10.7 Lion 上开发 - PHP 5.4.3
  • 在 Red Hat 6 - PHP 5.4.3 上运行生产
  • AD 服务器:Windows 2003

更新: 几个月后,我找不到这个问题的答案/解决方案。 最后,我将字符替换为非重音字符(我知道这不太理想)。

【问题讨论】:

  • 在其中一个值上使用bin2hex() 向我们展示二进制字符串值。
  • @deceze bin2hex( á ) == c3a1。我不确定这个角色是否会发生任何事情,因为它被复制并粘贴到各处。系统剪贴板可能会损坏/更改它(?)。
  • 我猜 LDAP/AD 是 Microsoft 版本的 LDAP 是在 WINDOWS-1250 编码,就像来自 Microsoft 的任何东西一样......因此 iconv("UTF-8", "WINDOWS-1250", $str); 应该可以工作。
  • 它不喜欢 WINDOWS-1250 - iconv(): Detected an illegal character in input string
  • 与php文件本身没有UTF8编码有什么关系吗?访问ldap的php文件应该将其编码类型设置为UTF-8?

标签: php encoding active-directory ldap


【解决方案1】:

您使用的是 LDAP v3 吗?

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

LDAPv3 默认支持 UTF-8,它希望请求和响应默认使用。见这里:http://technet.microsoft.com/en-us/library/cc961766.aspx

【讨论】:

  • 您是在 NIX 机器还是 Windows 机器上运行 LDAP 脚本。它是配置 AD 的同一台服务器吗?什么版本的 PHP?
  • 试试:iconv("UTF-8", "T.61", $str);
  • 好点;我已将要求的信息添加到问题中。 ...和:Wrong charset, conversion from 'UTF-8' to 'T.61' is not allowed :(
  • 试试ldap_8859_to_t61()ldap_t61_to_8859。看看这是否能让你转换
  • 这解决了我遇到的问题。它在手册中,但我过去看了 1000 次。
【解决方案2】:

这是对我有用的解决方案。做以下事情:

1.) 首先确保您使用的 LDAP 协议版本 3 正在使用 默认为“UTF-8”:

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

2.) 如果您想更改用户密码,请确保“使用 TLS”选项设置为 true 并使用 SSL 设置为 false

ldap_start_tls($ldapConnection);

3.) 我使用了端口号389

4.) 使用PHP函数ldap_mod_replace替换用户密码。

5.) 使用以下函数对您的$password 进行编码:

public function encodePassword($password)
{
    $password="\"".$password."\"";
    $encoded="";
    for ($i=0; $i <strlen($password); $i++){ 
        $encoded.="{$password{$i}}\000"; 
    }
    return $encoded;
}

6.) 使用以下逻辑更改用户密码:

$password="test";
if(mb_detect_encoding($password) == 'UTF-8')
{
    $password = utf8_decode($password);
}

$add=array();
$add["unicodePwd"][0] = encodePassword($password);

$result = @ldap_mod_replace($ldapConnection, $userDn, $add);
if ($result === false){
    //your action
}
else{
    //Your action
}

7.) 请注意,函数 encodePassword 将对您的 $password 转为 UTF-8 编码。如果您的密码是 UTF-8 编码的, 那么您必须先对其进行解码,然后再将其发送到 encodePassword 函数。这就是我写这行的原因:

if(mb_detect_encoding($password) == 'UTF-8')
{
    $password = utf8_decode($password);
}

当我在密码中提供德语变音符号时,此代码对我有用:äüößÄÜ 等...

【讨论】:

  • 设置这个完全解决了我的问题!!谢谢
【解决方案3】:

我已经设法通过两个步骤在 LDAP 中添加外来字符:

  • 仅使用 ASCII 字符添加用户 (iconv "ASCII//TRANSLIT")

  • 使用 ldapmodify 以 UTF-8 字符更新字段

LDAPv3 是 UTF-8,但我使用的工具(来自 smbldap-tools)没有正确处理它。

【讨论】:

    【解决方案4】:

    对于那些偶然发现这一点的人来说还有一件事:

    如果您的文本已经是 UTF-8,则不要尝试重新编码。请注意utf8_encode 文档页面上的以下备注。重新编码已经编码的字符串会导致文本乱码。此外,该函数只允许一种特定的编码到另一种。

    您可以通过执行以下操作轻松测试是否需要对字符串进行 UTF-8 编码:

    if (!preg_match('//u', $value)) {
        // do your encoding process...
    }
    

    关于网页上的字符也没有正确显示,但它们在 CLI 上,请确保您在标题中设置了正确的字符集:

    header('Content-type: text/html; charset=utf-8');

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      相关资源
      最近更新 更多