代码之家  ›  专栏  ›  技术社区  ›  MadMike Alpesh Gediya

CherryPy allways使用ISO-8859-1解码基本身份验证

  •  1
  • MadMike Alpesh Gediya  · 技术社区  · 7 年前

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

    使现代化

    已知限制记录在 issue #1680 .

    在问题解决之前,CherryPy不会识别UTF-8编码的基本身份验证数据。

    原始问题

    我在使用基本身份验证时遇到问题,名称/密码使用umlaut字符。似乎无法让http客户端发出ISO-8859-1(cherrypy将不支持该名称)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))"
    

    在cygwin上使用curl 7.56.1(i686 pc cygwin)进行测试,在redhat6上使用curl 7.19.7(x86\u 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上发送ISO-8851-15编码字符串的Firefox 57.0.2(32位)。

    此外,这并不能修复 cherrypy.request.login 价值

    1 回复  |  直到 7 年前
        1
  •  1
  •   Community CDub    3 年前

    更新(2018年4月22日):

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

    旧答案:

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

    我认为这个问题已经回答了。进一步的进展可以在相应的 CherryPy-Issue .