47

所以我试图实现以下场景:

  • 应用程序受基本身份验证保护。假设它托管在app.com
  • 应用程序前面的 HTTP 代理也需要身份验证。它托管在proxy.com

因此,用户必须在同一请求中为代理和应用程序提供凭据,因此他有不同的用户名/密码对:一对用于针对应用程序验证自己,另一个用户名/密码对用于针对代理验证自己。

阅读规范后,我不确定我应该如何实现这一点。我想做的是:

  1. 用户在没有任何身份验证的情况下向代理发出 HTTP 请求。
  2. 代理回答407 Proxy Authentication Required并返回Proxy-Authenticate格式为: 的标头"Proxy-Authenticate: Basic realm="proxy.com"
    问题:此Proxy-Authenticate标头设置正确吗?
  3. 客户端然后使用Proxy-Authorization标头重试请求,即代理的 Base64 表示username:password
  4. 这次代理对请求进行身份验证,但随后应用程序使用401 Unauthorized标头进行响应。用户由代理验证,但不是由应用程序验证。WWW-Authenticate应用程序会在响应中添加一个标头,例如WWW-Authenticate: Basic realm="app.com". 问题:此标头值正确吗?
  5. Proxy-Authorization客户端再次使用标头和标头重试请求,该标Authorization头的值是应用程序的 Base64 表示username:password
  6. 此时,代理成功地验证了请求,并将请求转发给对用户进行身份验证的应用程序。客户终于得到了回复。

整个工作流程是否正确?

4

1 回答 1

31

是的,对于您描述的情况,这看起来像是一个有效的工作流程,并且那些 Authenticate 标头似乎采用正确的格式。

有趣的是,一个给定的连接有可能(尽管不太可能)涉及链接在一起的多个代理,并且每个代理本身都可能需要身份验证。在这种情况下,每个中间代理的客户端本身会返回一条407 Proxy Authentication Required消息,并自己重复带有Proxy-Authorization标头的请求;和标头是单跳标头Proxy-AuthenticateProxy-Authorization不会从一个服务器传递到下一个服务器,而是WWW-AuthenticateAuthorization认为是从客户端到最终服务器的端到端标头,由中介逐字传递。

由于该Basic方案以明文形式发送密码(base64 是一种可逆编码),因此它最常用于 SSL。此方案以不同的方式实现,因为希望防止代理看到发送到最终服务器的密码:

  • 客户端打开到代理的 SSL 通道以发起请求,但不是提交常规 HTTP 请求,而是提交一个特殊CONNECT请求(仍然带有Proxy-Authorization标头)以打开到远程服务器的 TCP 隧道。
  • 然后,客户端继续创建另一个嵌套在第一个 SSL 通道中的 SSL 通道,在该通道上传输包括Authorization标头在内的最终 HTTP 消息。

在这种情况下,代理只知道客户端连接的主机和端口,而不是通过内部 SSL 通道传输或接收的内容。此外,嵌套通道的使用允许客户端“看到”代理和服务器的 SSL 证书,从而允许验证两者的身份。

于 2013-03-22T03:56:14.313 回答