我一直在寻找你要问的同样的事情。到目前为止,我还没有在 JDK 上找到一种方法来做到这一点。
有一个对 Java Bug 数据库进行增强的请求。查看该报告,了解 Sun 是否对此做出了回应(投票支持该报告,希望该问题很快得到解决)。
我最终做的是覆盖sun.net.www.protocol.http.NTLMAuthentication类。通过查看sun.net.www.protocol.http.HttpURLAuthentication,我发现您唯一需要修改的是以下结果:
NTLMAuthentication.supportsTransparentAuth()
true在 Windows 平台和false其他平台上,该方法具有硬编码的返回值。此代码是从安装在 Windows 7 上的 JDK 中提取的:
static boolean supportsTransparentAuth()
{
return true;
}
该方法告诉我们是否应该默认使用 Windows 凭据。如果设置为true,则不会调用您的自定义 Authenticator 代码。看到这个HttpURLConnection类的片段:
//Declared as a member variable of HttpURLConnection
private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth();
//Inside of getServerAuthentication method.
PasswordAuthentication a = null;
if (!tryTransparentNTLMServer) {
//If set to false, this will call Authenticator.requestPasswordAuthentication().
a = privilegedRequestPasswordAuthentication(url.getHost(), addr, port, url.getProtocol(), "", scheme, url, RequestorType.SERVER);
}
/* If we are not trying transparent authentication then
* we need to have a PasswordAuthentication instance. For
* transparent authentication (Windows only) the username
* and password will be picked up from the current logged
* on users credentials.
*/
if (tryTransparentNTLMServer || (!tryTransparentNTLMServer && a != null)) {
//If set to true or if Authenticator did not return any credentials, use Windows credentials.
//NTLMAuthentication constructor, if receives a == null will fetch current looged user credentials.
ret = new NTLMAuthentication(false, url1, a);
}
为了获取NTLMAuthentication源代码,我使用了这个 Java 反编译器。打开位于 JDK 安装文件夹中的 rt.jar 并复制所需的类代码。
然后,我干脆改成supportsTransparentAuth返回false。但是,如果此方法首先检查系统属性,然后根据该属性返回 true 或 false,那将是非常可取的。
为了编译它,我只是将 java 文件放在 sun/net/www/protocol/http 文件夹结构下并运行:
javac NTLMAuthentication.java
然后使用以下命令运行我的应用程序:
java -Xbootclasspath:"path/to/your/sun/net/www/protocol/http/classes;normal/JDK/boot/directories"
这将告诉 JVMNTLMAuthentication在 rt.jar 中加载我们之前的实现。您必须小心不要错过任何带有 的默认类加载路径-Xbootclasspath,否则会出现ClassNotFound错误。
之后,一切正常。
这种方法具有您应该注意的重要缺点。
- 存在安全风险。任何人都可以在您的引导文件夹中放置不同的 .class 文件并窃取用户凭据或其他重要信息。
- Sun 软件包中的代码可能会更改,恕不另行通知,因此与您的更改不兼容。
- 如果您部署此代码,您将违反 Sun 代码许可证。从文档中:
-Xbootclasspath:bootclasspath 指定以分号分隔的目录、JAR 归档和 ZIP 归档列表以搜索引导类文件。这些用于代替 Java 2 SDK 中包含的引导类文件。注意:不应部署使用此选项来覆盖 rt.jar 中的类的应用程序,因为这样做会违反 Java 2 运行时环境二进制代码许可证。
所以,这绝对不适合生产环境。
最后,这是一个关于引导类路径选项和 Java 类加载器的优秀资源:PDF
希望这可以帮助。