Проблема кодирования 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')