问题描述
我在Ubuntu 14.04.2(x86_64)和python 3.4.0上将Apache 2.4.7与mod_wsgi 3.4一起使用.我的python应用程序依靠apache对我们公司的LDAP服务器(MS Active Directory 2008)执行用户身份验证.它还使用操作系统环境将一些其他LDAP数据传递到python应用程序.在apache配置中,我像这样查询LDAP:
I am using Apache 2.4.7 with mod_wsgi 3.4 on Ubuntu 14.04.2 (x86_64) and python 3.4.0. My python app relies on apache to perform user authentication against our company’s LDAP server (MS Active Directory 2008). It also passes some additional LDAP data to the python app using the OS environment. In the apache config, I query the LDAP like so:
…
AuthLDAPURL "ldap://server:389/DC=company,DC=lokal?sAMAccountName,sn,givenName,mail,memberOf?sub?(objectClass=*)"
AuthLDAPBindDN …
AuthLDAPBindPassword …
AuthLDAPRemoteUserAttribute sAMAccountName
AuthLDAPAuthorizePrefix AUTHENTICATE_
…
这会将一些用户数据传递到我的WSGI脚本中,在该脚本中,我按如下方式处理信息:
This passes some user data to my WSGI script where I handle the info as follows:
# 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)
然后我可以使用os.environ.get(…)
在我的python应用程序中访问此信息. (顺便说一句:如果您有更好的解决方案,请告诉我!)
I can then access this info in my python app using os.environ.get(…)
. (BTW: If you have a more elegant solution, please let me know!)
问题在于某些用户名包含未正确编码的特殊字符(德国变音符号,例如äöüÄÖÜ
).因此,例如,名称Tölle
作为Tölle
到达我的python应用中.
The problem is that some of the user names contain special characters (German umlauts, e.g., äöüÄÖÜ
) that are not encoded correctly. So, for example, the name Tölle
arrives in my python app as Tölle
.
显然,这是一个编码问题,因为
Obviously, this is an encoding problem, because
$ echo "Tölle" | iconv --from utf-8 --to latin1
给我正确的Tölle
.
另一个可能有用的发现:在我的Apache日志中,我找到了表示为\xc3\x83\xc2\xbc
的字符ü
.
Another observation that might help: in my apache logs I found the character ü
represented as \xc3\x83\xc2\xbc
.
我告诉/etc/apache2/envvars
中的Apache使用LANG=de_DE.UTF-8
,并且python 3也支持utf-8.我似乎无法指定有关LDAP服务器的任何信息.所以我的问题是:编码在哪里混淆了,我该如何修补?
I told my Apache in /etc/apache2/envvars
to use LANG=de_DE.UTF-8
and python 3 is utf-8 aware as well. I can’t seem to specify anything about my LDAP server. So my question is: where is the encoding getting mixed up and how do I mend it?
推荐答案
在每个请求上将值复制到os.environ
是不好的做法,因为如果WSGI服务器在多线程配置下运行,并且并发运行,将导致失败请求互相干扰.而是查看线程局部变量.
It is bad practice to copy the values to os.environ
on each request as this will fail miserable if the WSGI server is running with a multithreaded configuration, with concurrent requests interfering with each other. Look at thread locals instead.
关于LDAP编码数据的问题,如果我理解这个问题,则需要这样做:
As to the issue of encoded data from LDAP, if I under stand the problem, you would need to do:
"Tölle".encode('latin-1').decode('utf-8')
这篇关于Apache,LDAP和WSGI编码问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!