每个连接基础上的Java验证器?

16
我正在构建一个与使用基本身份验证的REST接口进行通信的Eclipse插件。当身份验证失败时,我希望弹出插件的设置对话框并重试。通常情况下,我可以使用静态的Authenticator.setDefault()为所有HttpURLConnection设置一个身份验证器,但由于我正在编写一个插件,我不想覆盖Eclipse的默认Authenticatororg.eclipse.ui.internal.net.auth)。
我考虑在加载之前设置自定义的Authenticator,然后在加载之后恢复Eclipse的默认设置,但我想象中这将导致各种多线程竞争问题,所以我很快放弃了这个想法。
谷歌搜索给出了各种结果,基本上告诉我这是不可能的:
引用: Java的URLConnection API应该有一个setAuthenticator(Authenticator)方法,以便在需要身份验证的多线程环境中更容易使用这个类。 来源 如果应用程序包含少量第三方插件,并且每个插件都使用自己的验证器,我们应该怎么办?每次调用"Authenticator.setDefault()"方法都会覆盖先前定义的验证器... 来源 有没有其他方法可以帮助我解决这个问题?

1
+1 我有同样的问题。非常烦人! - Mike Tunnicliffe
2个回答

11

如果使用HttpURLConnection不可行,我建议使用Apache的httpclient库。

一个快速示例:

HttpClient client = new HttpClient();
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test","test"));
GetMethod getMethod = new GetMethod("http://www.example.com/mylogin");
client.executeMethod(getMethod);
System.out.println(getMethod.getResponseBodyAsString());

是的,如果JRE默认的HttpURLConnection无法解决这个问题,我已经决定使用Apache Commons Http Client。不过还是谢谢你的回答! - Martijn Laarman
最终选择第三方的Http类是唯一可行的解决方案,所以我会接受你的答案。 - Martijn Laarman

2

另一种方法是在连接上自己执行基本身份验证。

    final byte[] encodedBytes = Base64.encodeData((username + ':' + new String(password)).getBytes("iso-8859-1"));
    final String encoded = new String(encodedBytes, "iso-8859-1");

    connection.setRequestProperty("Authorization", "Basic " + encoded);

这样做的好处是不需要在后续请求中收到401响应码后再提供凭证,避免了未经身份验证的请求。通过请求预先认证,可以在Apache HTTP客户端中实现类似的行为。

非常感谢!你救了我的一天。Authenticator.setDefault 简直是个罪行... - marcolopes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接