RFC2617规定将用户名和密码编码为base64,但未指明创建输入到base64算法的八位字节时使用哪种字符编码。
我应该假设是US-ASCII还是UTF8?或者已经有人在某处解决了这个问题吗?
RFC2617规定将用户名和密码编码为base64,但未指明创建输入到base64算法的八位字节时使用哪种字符编码。
我应该假设是US-ASCII还是UTF8?或者已经有人在某处解决了这个问题吗?
RFC 2617 可以被解读为“ISO-8859-1”或“未定义”。由你决定。众所周知,许多服务器使用 ISO-8859-1(不管你喜欢与否),并且在发送其他内容时会失败。因此,唯一安全的选择可能是坚持使用 ASCII。
有关更多信息和修复该情况的提案,请参见草案"HTTP基本身份验证的编码参数"(这是 RFC 7617 的基础)。
自2015年以来,RFC 7617已经取代了RFC 2617。与旧的RFC相比,新的RFC明确定义了用于用户名和密码的字符编码。
charset="UTF-8"
,如下所示:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
完整版本:
阅读规范。它包含了其他细节,例如确切的编码过程和应支持的Unicode代码点列表。
截至2018年,现代浏览器通常会默认使用UTF-8编码,即使服务器不使用charset
参数,用户输入非ASCII字符作为用户名或密码时也是如此。
即使在RFC 7617中,realm参数仍然只支持ASCII字符。
realm
是一个quoted-string
,并且RFC 7230中定义的quoted-string
允许使用高达0xFF的八位字节,因此人们认为UTF-8可以被使用。 - Remy Lebeaubasic-credentials = base64-user-pass
base64-user-pass = <base64 encoding of user-pass,
except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
阅读本规范时应参考RFC2616(HTTP 1.1)中的BNF定义(如上所述):
本规范是HTTP/1.1规范2的附属规范。 它使用该文档的增强型BNF第2.1节,并依赖于 该文档中定义的非终端符号和HTTP/1.1规范的其他方面。
RFC2616,第2.1节定义了TEXT(我强调):
TEXT规则仅用于描述性字段内容和值, 这些内容和值不打算由消息解析器解释。* TEXT的单词 当按照RFC 2047的规则进行编码时,可以包含来自字符集的字符 ISO-8859-1以外的字符集。
TEXT = <any OCTET except CTLs, but including LWS>
// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=
0xA4
。我的理解是,您应该检查这些编码的字词分隔符,然后根据指定的编码对内部字词进行解码。如果不这样做,您将认为密码是=?iso-8859-15?q?T¤ST?=
(请注意,当作为iso-8859-1解释时,0xA4
将被解码为¤
)。消息格式以允许使用字符集其他于US-ASCII的文本标题信息。
但是,RFC2616(HTTP 1.1)使用TEXT规则定义标题,默认为iso-8859-1。那么这意味着此标题中的每个单词都应该是一个编码单词(即=?...?=
形式)吗?
同样相关的是,目前没有任何浏览器可以做到这一点。它们使用utf-8(Chrome,Opera),iso-8859-1(Safari),系统代码页(IE)或其他一些编码方式(例如Firefox只使用utf-8的最高有效位)。
编辑:我刚意识到这个答案更多地从服务器端的角度来看待这个问题。
User: 豚 (\u8c5a)
Password: 虎 (\u864e)
编码与以下相同:
User: Z (\u005a)
Password: N (\u004e)
将0x5a 0x3a 0x4e转换为base64编码后为WjpO。
BasicAuthenticationFilter
类使用的编码是UTF-8。