CherryPy始终使用ISO-8859-1解码Basic Auth

时间:2017-12-28 15:02:04

标签: python character-encoding cherrypy http-basic-authentication

有没有办法配置cherrypy来正确解码utf-8编码的身份验证字符串?

更新

issue #1680中记录的已知限制。

在问题解决之前,CherryPy将无法识别UTF-8编码的Basic-Auth数据。

原始问题

我无法使用带有变音字符的名字/密码的basic-auth。似乎没有办法让http-client发出ISO-8859-1(cherrypy将unterstand)name:password或配置cherrypy以使用utf-8解码认证字符串。

使用Python 3.6和CherryPy 13.1.0:

import cherrypy

class SimpleWebpage(object):
    @cherrypy.expose
    def index(self):
        return "<html><head></head><body>Authenticated</body></html>"

def dummy_validate(realm, username, password):
    print("realm: {realm!r}, username: {username!r}, password: {password!r}".format_map(locals()))
    return True

cherrypy.tree.mount(SimpleWebpage(), '/',
                    {'/': {'tools.auth_basic.checkpassword': dummy_validate,
                           'tools.auth_basic.on': True,
                           'tools.auth_basic.realm': 'MY_REALM',}})

cherrypy.config.update({'tools.sessions.on': True,})

cherrypy.engine.autoreload.unsubscribe()
cherrypy.engine.start()
cherrypy.engine.block()

使用以下参数调用curl:

curl -u 'Céline:motörhead' -i -X GET http://127.0.0.1:8080/

将从cherrypy控制台提供以下输出:

[28/Dec/2017:15:52:57] ENGINE Bus STARTING
[28/Dec/2017:15:52:57] ENGINE Serving on http://127.0.0.1:8080
[28/Dec/2017:15:52:57] ENGINE Bus STARTED
realm: 'MY_REALM', username: 'Céline', password: 'motörhead'
127.0.0.1 - C\xc3\x83\xc2\xa9line [28/Dec/2017:15:53:18] "GET / HTTP/1.1" 200 52 "" "Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))"

在redhat6上使用curl 7.56.1(i686-pc-cygwin)在cygwin和curl 7.19.7(x86_64-redhat-linux-gnu)上测试。我也用google-chrome 63.0.3239.108测试了它,结果完全相同。

Kludge

def decode_utf8(s):
    s_bytes = bytes([ord(c) for c in s])
    return s_bytes.decode('utf-8')

def dummy_validate(realm, username, password):
    username = decode_utf8(username)
    password = decode_utf8(password)
    print("realm: {realm!r}, username: {username!r}, password: {password!r}".format_map(locals()))
    return True

使用此代码将为我提供google-chrome和curl的正确结果。但它不适用于(作为示例)Windows 10上的Firefox 57.0.2(32位),它发送ISO-8851-15编码的字符串。

这也无法修复cherrypy.request.login值。

1 个答案:

答案 0 :(得分:1)

更新(2018年4月22日):

由于CherryPy v14.2.0 auth_basicauth_digest工具在HTTP客户端(浏览器)支持的范围内支持RFC 7617,因此在某些情况下往往会发送损坏的数据。

旧答案:

正如@webKnjaZ已在评论中批准,这是一个需要在CherryPy或cheroot中解决的错误。

我认为这个问题已经回答了。可以在相应的CherryPy-Issue上跟踪相关错误的进一步进展。