Java:通过 NTLM 代理的 HTTP(S)/WebServices 连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17527081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 02:12:59  来源:igfitidea点击:

Java : HTTP(S)/WebServices connections through NTLM proxy

javaproxyhttpurlconnectionntlm

提问by Nicolas A.

We have a java client side application deployed in our customer (a java application, not an applet). This application checks connectivity with an url.openConnection() and calls web services (with CXF/JAX-WS) through internet.

我们在客户中部署了一个 Java 客户端应用程序(一个 Java 应用程序,而不是一个小程序)。此应用程序检查与 url.openConnection() 的连接并通过 Internet 调用 Web 服务(使用 CXF/JAX-WS)。

Some of our customer network use proxies to access to the external world. The client side application sets the proxy parameter in java system properties :

我们的一些客户网络使用代理访问外部世界。客户端应用程序在 java 系统属性中设置代理参数:

System.setProperty("proxySet", "true");   //Obsolete ?
System.setProperty("http.keepAlive", "false");
System.setProperty("java.net.useSystemProxies", "false");
System.setProperty("https.proxyHost", httpsProxyHost);
System.setProperty("https.proxyPort", httpsProxyPort);
System.setProperty("https.proxyUser", httpsProxyUser);
System.setProperty("https.proxyPassword", httpsProxyPassword);
System.setProperty("http.proxyHost", httpProxyHost);
System.setProperty("http.proxyPort", httpProxyPort);
System.setProperty("http.proxyUser", httpProxyUser);
System.setProperty("http.proxyPassword", httpProxyPassword);

Authenticator.setDefault(new NtlmAuthenticator(httpsProxyUser, httpsProxyPassword));

The NtlmAuthenticator class :

NtlmAuthenticator 类:

public class NtlmAuthenticator extends Authenticator {

private final String username;
private final char[] password;

public NtlmAuthenticator(final String username, final String password) {
    super();
    this.username = username;
    this.password = password.toCharArray(); 
}

public PasswordAuthentication getPasswordAuthentication() {
    return (new PasswordAuthentication (username, password));
}

}

}

We're using Java 6 (client side application embbed a JRE 1.6.0_39), and application is deployed on Windows (XP / Seven). I read that NTLM protocol is supported since 1.4.2 on Windows platform. So we made tests with a Trend proxy and succeed to perform NTLM proxy authentication (we see the 3 packets with Wireshark NTLMSSP_NEGOCIATE (from app) / NTLMSSP_CHALLENGE (from proxy) / NTLMSSP_AUTH (from app))

我们使用 Java 6(客户端应用程序嵌入了 JRE 1.6.0_39),并且应用程序部署在 Windows(XP / 7)上。我读到 Windows 平台上自 1.4.2 起就支持 NTLM 协议。所以我们用Trend代理进行了测试并成功执行了NTLM代理认证(我们看到了3个带有Wireshark NTLMSSP_NEGOCIATE(来自app)/NTLMSSP_CHALLENGE(来自代理)/NTLMSSP_AUTH(来自app)的数据包)

But with one of our customers, who use a Bluecoat proxy, NTLM authentication failed after NTLMSSP_CHALLENGE. With Wireshark, we only see the 2 first packets NTLMSSP_NEGOCIATE (from app) and NTLMSSP_CHALLENGE (from proxy), NTLMSSP_AUTH is never sent by our application. In the application we catch a SocketException : socket is closed

但是对于我们的一位使用 Bluecoat 代理的客户,NTLM 身份验证在 NTLMSSP_CHALLENGE 后失败。使用 Wireshark,我们只能看到前 2 个数据包 NTLMSSP_NEGOCIATE(来自应用程序)和 NTLMSSP_CHALLENGE(来自代理),我们的应用程序从不发送 NTLMSSP_AUTH。在应用程序中,我们捕获了一个 SocketException :套接字已关闭

We also try to use jCIFS HttpUrlNltmHandler, but authentication failed too (same diagnostic).

我们也尝试使用 jCIFS HttpUrlNltmHandler,但身份验证也失败了(同样的诊断)。

I found this threadwith similar issue but it doesn't provide any clues. I found also this threadabout NTLM session security

我发现这个线程有类似的问题,但它没有提供任何线索。我还发现了这个关于 NTLM 会话安全的线程

Any ideas ?

有任何想法吗 ?

Thanks.

谢谢。

Find the solution just by setting http.keepalive to true : System.setProperty("http.keepAlive", "true");

只需将 http.keepalive 设置为 true 即可找到解决方案: System.setProperty("http.keepAlive", " true");

But i don't know why, with false value, it works with our Trend proxy and doesn't work with our customer's bluecoat proxy

但我不知道为什么,如果值错误,它可以与我们的 Trend 代理一起使用,而不能与我们客户的 bluecoat 代理一起使用

采纳答案by Carlo Pellegrini

It's due to a bug on the underlying implementation. It's described on Java 6 NTLM proxy authentication and HTTPS - has anyone got it to work?

这是由于底层实现上的错误。它在Java 6 NTLM 代理身份验证和 HTTPS 中有描述- 有没有人让它工作?