Java 代理身份验证

标签 java authentication networking proxy

我有一个在 Tomcat 6 中运行的 Java 网络应用程序,它从远程 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。

最佳答案

我们在此处对基于 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 .

关于Java 代理身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8669726/

相关文章:

c++ - 从连接管理器获取 wi-fi 连接状态

networking - 通过 IP 访问 IISExpress 以获取 asp.net 核心 API

unix - 无法连接到 beaglebone.local

java - 将 xml 从第 n 个元素拆分为第 x 个元素

java - 使用java修剪json对象中的冗余属性

java - 从 MDB 调用时如何调用具有特定角色的 session bean 方法?

Objective-c HTTP 基本身份验证

java - 使用数组让访客登录管理系统

linux - 如何将从一个网络接口(interface)收到的数据包重定向到另一个网络接口(interface)?

java - Hibernate 使用条件删除