我有一个在Tomcat 6中运行的Java webapp,它从远程URL加载RSS提要。
我使用Rome为我处理RSS提要和不同的格式。连接部分看起来像这样:
try{
feedSource = new URL(rssObject.getAsset());
}catch(MalformedURLException mue){
logger.error(...);
throw mue;
}
try{
URLConnection connection = feedSource.openConnection();
feed = new SyndFeedInput().build(new XmlReader(connection));
}catch(Exception){handle...}
代码工作正常,除了在这个新客户端,他们使用代理。
为了使用代理,我设置了http.proxyHost和proxyPort系统属性:
System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", proxyPort);
System.setProperty("https.proxyHost", proxyHost);
System.setProperty("https.proxyPort", proxyPort);
HTTP GET是代理好的,但现在我收到HTTP 502错误(坏网关或类似的东西)。
分析与Wireshark的HTTP交换,我注意到代理需要身份验证。它发送HTTP 507. Java以某种方式尝试进行身份验证,但它使用了错误的用户名和密码。它似乎使用主机名作为用户名,对于我不知道的密码。
所以我尝试实现了指定用户名+密码的Authenticator方法:
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
logger.info(MessageFormat.format("Generating PasswordAuthentitcation for proxy authentication, using username={0} and password={1}.", username, password));
return new PasswordAuthentication(username, password.toCharArray());
}
});
现在我的问题是它被忽略了。永远不会调用getPasswordAuthentication方法。我没有在日志文件中看到日志语句并使用Wireshark我可以看到它仍然使用主机名作为用户名。
为什么?似乎java在某种程度上试图在不咨询Authenticator的情况下自行进行身份验证。
代理似乎是使用NTLM进行身份验证的MS设备。 java中是否有一些内置机制来处理这个问题?运行应用程序的计算机是Win Server 2008 R2。
答案 0 :(得分:12)
我们在此处对基于NTLM的代理进行身份验证做了同样的事情。
代理上的身份验证实际上是正常的 HTTP基本身份验证。
我们使用以下方法:
protected URLConnection newURLConnection(URL pURL) throws IOException {
URLConnection urlConnection = super.newURLConnection(pURL);
String auth = new String(Base64.base64Encode(new String("username:password").getBytes()));
auth = "Basic " + auth;
urlConnection.setRequestProperty("Proxy-Connection","Keep-Alive");
urlConnection.setRequestProperty("Proxy-Authorization",auth);
return urlConnection;
}
这与代理jvm设置一起完成了这个伎俩。
请参阅http://en.wikipedia.org/wiki/Basic_access_authentication。