Проблема кодирования Apache, LDAP и WSGI

Я использую Apache 2.4.7 с mod_wsgi 3.4 на Ubuntu 14.04.2 (x86_64) и python 3.4.0. Мое приложение на python использует apache для выполнения аутентификации пользователя на сервере LDAP нашей компании (MS Active Directory 2008). Он также передает некоторые дополнительные данные LDAP в приложение python, используя среду ОС. В конфигурации Apache я запрашиваю LDAP следующим образом:

…
AuthLDAPURL "ldap://server:389/DC=company,DC=lokal?sAMAccountName,sn,givenName,mail,memberOf?sub?(objectClass=*)"
AuthLDAPBindDN …
AuthLDAPBindPassword …
AuthLDAPRemoteUserAttribute sAMAccountName
AuthLDAPAuthorizePrefix AUTHENTICATE_
…

Это передает некоторые пользовательские данные моему сценарию WSGI, где я обрабатываю информацию следующим образом:

# Make sure the packages from the virtualenv are found
import site
site.addsitedir('/home/user/.virtualenvs/ispot-cons/lib/python3.4/site-packages')

# Patch path for app (so that libispot can be found)
import sys
sys.path.insert(0, '/var/www/my-app/')

import os
from libispot.web import app as _application

def application(environ, start_response):
    os.environ['REMOTE_USER'] = environ.get('REMOTE_USER', "")
    os.environ['REMOTE_USER_FIRST_NAME'] = environ.get('AUTHENTICATE_GIVENNAME', "")
    os.environ['REMOTE_USER_LAST_NAME'] = environ.get('AUTHENTICATE_SN', "")
    os.environ['REMOTE_USER_EMAIL'] = environ.get('AUTHENTICATE_MAIL', "")
    os.environ['REMOTE_USER_GROUPS'] = environ.get('AUTHENTICATE_MEMBEROF', "")
    return _application(environ, start_response)

Затем я могу получить доступ к этой информации в моем приложении Python, используя os.environ.get(…), (Кстати: если у вас есть более элегантное решение, пожалуйста, дайте мне знать!)

Проблема в том, что некоторые имена пользователей содержат специальные символы (например, немецкие умляуты, äöüÄÖÜ), которые не закодированы правильно. Так, например, имя Tölle прибывает в мое приложение на Python как Tölle,

Очевидно, что это проблема кодирования, потому что

$ echo "Tölle" | iconv --from utf-8 --to latin1 

дает мне правильный Tölle,

Еще одно наблюдение, которое может помочь: в моих логах apache я нашел персонажа ü представлен как \xc3\x83\xc2\xbc,

Я сказал мой Apache в /etc/apache2/envvars использовать LANG=de_DE.UTF-8 и python 3 также поддерживает utf-8. Я не могу указать что-либо о моем сервере LDAP. Итак, мой вопрос: где смешивается кодировка и как ее исправить?

1 ответ

Решение

Это плохая практика, чтобы скопировать значения в os.environ на каждый запрос, так как это будет неудачным, если сервер WSGI работает с многопоточной конфигурацией, а параллельные запросы мешают друг другу. Посмотрите на местных жителей потока вместо этого.

Что касается вопроса о закодированных данных из LDAP, если я понимаю проблему, вам нужно сделать:

"Tölle".encode('latin-1').decode('utf-8')
Другие вопросы по тегам