我正在使用Jersey Client 2.0库(带有Apache HttpClient v4.2.5传输连接器)来使用RESTful Web服务。我的应用程序必须支持具有基本,摘要或NTLM身份验证的代理服务器连接。我已经添加了对所有这些类型的代理身份验证的支持,并且基本上一切正常。
这是我添加了对基本和摘要代理身份验证的支持的方式:
ClientConfig config = new ClientConfig();
config.property(ApacheClientProperties.PROXY_URI, "http://www.proxy.com:5678");
config.property(ApacheClientProperties.PROXY_USERNAME, "proxy_user");
config.property(ApacheClientProperties.PROXY_PASSWORD, "proxy_password");
ApacheConnector connector = new ApacheConnector(config);
config.connector(connector);
Client client = ClientBuilder.newClient(config);
另外,我要连接的RESTful Web服务本身也需要基本身份验证,我将使用以下方法进行处理:
client.register( new HttpBasicAuthFilter("user", "password") );
但是,我的应用程序运行不尽如人意:我发出的每个单独的HTTP请求似乎都导致来自代理服务器的407身份验证质询响应。这是一个问题,有两个原因:
如果我使用an提供的实体发出aPOST
或PUT
请求(已在上一个请求中成功地通过代理服务器进行了身份验证),则该请求InputStream
被视为“不可重复的”请求,因此当收到407质询时,我会收到以下例外:
org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
我可以通过将实体数据从缓存InputStream
到字符串或字节数组中来解决此问题,以便在收到407质询的情况下可以重复请求,但这效率低下,无法解决问题2。
我的期望是,一旦Jersey客户端第一次成功通过代理服务器进行身份验证,使用相同Client
实例发出的所有后续请求将自动包含必要的Proxy-Authorization
标头,以防止发生任何其他407挑战。根据此链接,这似乎是HTTP 1.1的标准方法:
代理服务器在407(要求代理身份验证)响应中向客户端发送包含挑战的Proxy-Authenticate标头。然后,客户端重复初始请求,但添加一个Proxy-Authorization标头,其中包含适用于质询的凭据。成功进行代理身份验证后,客户端通常会随每个后续请求将相同的代理授权标头发送给代理,而不是等待再次受到挑战。
因此,我的问题是我需要将哪些配置设置应用于Jersey客户端或基础Apache HttpClient传输层才能启用此行为?我看过其他各种文章,建议手动添加Proxy-Authorization
标题,但如果可能的话,我宁愿避免这种解决方法。理想情况下,我也在寻找一种适用于我正在使用的所有三种类型的代理身份验证(基本,摘要和NTLM)的解决方案。
如果无法防止所有这些额外的407挑战,那么我还希望以“可重复”的方式从本地文件中张贴或放置数据时,建议最佳方法的建议,以防止407代理身份验证挑战后出现问题。
最后,我解决了问题1,方法是将项目升级到Jersey Client v2.6,并将客户端配置为自动缓冲所有POST / PUT请求,以使它们“可重复”以响应从代理返回的任何407个挑战服务器。
通过在ClientConfig
对象上设置以下属性,可以在Jersey Client v2.5 +中启用请求缓冲,该属性将请求实体处理模式从“块化”(默认)更改为“缓冲”:
config.property(ClientProperties.REQUEST_ENTITY_PROCESSING,
RequestEntityProcessing.BUFFERED);
现在,我可以使用我必须支持的所有三种类型的代理身份验证:基本,摘要和NTLM。我仅在用户配置了代理服务器时才启用此“缓冲”模式,因为我认为除非绝对必要,否则最好坚持使用默认的“分块”模式。我担心的是在内存中缓冲大型PUT / POST请求的开销,以及不对数据进行分块的潜在效率损失。
因此,现在我的客户端应用程序可以正常运行,但是我仍然非常有兴趣了解问题2的任何可能解决方案,因为最好是每个Client
实例仅触发一个初始的407代理身份验证质询。我怀疑由于Digest和NTLM身份验证固有的额外复杂性,此问题的任何潜在解决方案无论如何都只能用于基本身份验证。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句