Иностранные символы и LDAP. Какую кодировку / кодировку ожидает LDAP?
я разбираю XML, с simplexml_load_string()
и использование данных в нем для обновления объектов Active Directory (AD) через LDAP.
пример 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()
найти одного пользователя, а затем приступить к изменению их свойств. Накачка вышеуказанных значений прямо в AD, используя LDAP, приведет к появлению некоторых довольно искаженных символов.
например: 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 покажет правильные символы, но веб-браузеры показывают то же самое, что и AD.
что происходит? Должен ли я смотреть на что-то другое, например. URL-АДРЕС кодирование? Я надеюсь, что это просто ошибка с моей стороны.
EDIT:
Я ввел эти символы с помощью ad admin GUI, чтобы увидеть, как они выйдут. Я могу прочитать их через LDAP. Правильные символы отображаются в браузере. curl-ing через 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 server: Windows 2003
обновление: Через несколько месяцев, я не смог найти ответ/решение этой проблемы. В конце концов, я пошел с заменой персонажи к их не акцентированному эквиваленту (не идеальному, Я знаю).
4 ответов
вы используете LDAP v3?
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
LDAPv3 поддерживает UTF-8 по умолчанию, который он ожидает, что запросы и ответы будут по умолчанию. Смотрите здесь: http://technet.microsoft.com/en-us/library/cc961766.aspx
мне удалось добавить иностранные символы в LDAP с двумя шагами:
Добавить пользователя только с символами ASCII (iconv "ASCII//TRANSLIT")
использовать
ldapmodify
для обновления полей UTF-8 символами
LDAPv3-UTF-8, но инструмент, который я использовал (от smbldap-tools
) не справлялся с этим должным образом.
вот решение, которое сработало для меня. Делайте следующие вещи:
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}}0";
}
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,
затем нужно расшифровать его перед отправкой
if(mb_detect_encoding($password) == 'UTF-8')
{
$password = utf8_decode($password);
}
этот код работал для меня, когда я предоставьте немецкие Umlauts в пароле:äüößÄÜ
etc...
еще одна вещь, чтобы упомянуть для тех, кто натыкается на это:
Если ваш текст уже находится в UTF-8, Не пытайтесь его перекодировать. Обратите внимание на следующие замечания на странице doc для utf8_encode. Повторное кодирование уже закодированной строки приведет к искажению текста. Кроме того, функция позволяет использовать только одну конкретную кодировку для другой.
Вы можете легко проверить, нужно ли UTF-8 кодировать строку, делая что-то например:
if (!preg_match('//u', $value)) {
// do your encoding process...
}
Что касается символов, которые не отображаются правильно на веб-странице, но они находятся на CLI, убедитесь, что вы устанавливаете правильную кодировку в своих заголовках:
header('Content-type: text/html; charset=utf-8');