在这个问题上,我一直在用头撞墙。我读过类似的帖子和文章;大多数建议在 Tomcat 的 server.xml 文件中将 URIEncoding 设置为 UTF-8,但这在这里似乎没有什么区别。
我有一个 ReSTful Web 服务部署到托管在 Tomcat 7 上的测试环境。Tomcat 被配置为使用 Java 6,尽管 Java 7 也安装在机器上。对托管在那里的服务运行基本身份验证测试时,登录失败,当原始凭据包含 Unicode 字符时,我收到 HTTP 状态 401 的响应。当凭据仅包含 ASCII 时,基本身份验证工作正常。我也可以完全不使用基本身份验证登录 - 我的服务支持自定义登录标头和 RFC 2047。使用这种方法,凭据是否包含 Unicode 都没有关系,登录不是问题。
具体来说,“问题”似乎是用户名被 UTF-8 编码两次。我的记录器(单独的问题)中有一个错误,其中日志文件是 ANSI 编码的。当您将日志文件转换为 UTF-8 时,字符将正确显示。但是在这种情况下,有问题的用户名比它应该的长得多,当文件转换为 UTF-8 时,它看起来就像它最初应该有的一样(在转换之前)。例如:
- BAD (BASIC AUTH): SampleUser-¢𣎴eÌ‚é¾± -> SampleUser-¢𣎴ê龱</li>
- 好的(RFC 2047):SampleUser-¢𣎴eÌ‚é¾± -> SampleUser-¢ê龱</li>
这里真正的问题是我有自己的 Tomcat 7 (Java 6) 实例在本地运行,但我无法针对它重现问题。我比较了两个 Tomcat 的 conf 目录,它们看起来是一样的。我无法弄清楚为什么基本身份验证在一种环境中工作而不是在另一种环境中工作。我正在从我的机器上运行测试,所以这不可能是由于我测试它的方式(JUnit/JSystem)的差异。
这是我所知道的:
- 就特权而言,我们谈论的用户类型无关紧要。用户名中的 Unicode 是有问题的因素。
- 请求是通过 XML 还是 JSON 发送并不重要。我的服务支持这两种类型的序列化。
- 接受字符集和内容类型(如果适用)在请求中都设置为 UTF-8。
- Java 系统属性在两种环境中是相同的。
以下文章对我来说非常有趣,因为它们提出了将 RFC 2047 和基本身份验证结合在一起的可能性。我不认为这是必要的,因为基本的身份验证字符串本身只包含 ASCII(因为它是 base-64 编码的)。即使是这样,为什么在一台 Tomcat 服务器而不是另一台服务器上需要这样的东西?我觉得追求这种组合方法并没有解决根本问题,这才是真正让我发疯的原因!
- http://www.mentby.com/Group/tomcat-user/basic-authentication-failed-with-multibyte-username.html
- 我应该为 HTTP 基本身份验证使用什么编码?
提前感谢您提供有关尝试或仔细检查的建议。测试环境对我来说有点局限——我只能在下班时间“玩”,所以如果我没有及时回复,我提前道歉。