是否可以在Windows上禁用Java的“单点登录"(使用“凭据管理器"中的凭据)? [英] Can Java's 'single sign-on' (use credentials from 'Credential Manager') on Windows be disabled?
问题描述
Oracle的"Http身份验证" 页显示:如果您以域用户的身份在Windows计算机上运行,或者您在已经发出kinit
命令并获得凭据缓存的Linux或Solaris计算机上运行"然后将该实例传递给 Authenticator.setDefault()
将被完全忽略".
Oracle's "Http Authentication" page from the Java SE 6 documentation says that "if you are running on a Windows machine as a domain user, or, you are running on a Linux or Solaris machine that has already issued the kinit
command and got the credential cache" then the instance passed to Authenticator.setDefault()
"will be completely ignored".
这与我观察到的情况相符:在Windows系统上为主机X设置HTTP或HTTPS连接,总是从"Windows保险柜"的"Windows凭据"传递主机X的凭据,如Windows 7中所示凭据管理器的控制面板"页面.
This matches what I observed: setting up an HTTP or HTTPS connection on a Windows system to host X always passes the credentials for host X from the 'Windows Credentials' of the 'Windows Vault', as seen in my Windows 7 'Credential Manager' Control Panel page.
但是,在我的用例中,我不想使用Windows可能存储的任何凭据,但是我总是想使用我在代码中明确指定的凭据.
However, in my use case I don't want to use any credentials which might be stored by Windows, but instead I always want to use credentials I explicitly specify in the code.
是否有方法可以覆盖已记录的行为,即是否有方法可以忽略Windows存储的凭据?
Is there a way to override the documented behavior, i.e., is there a way to ignore the credentials stored by Windows?
更新:如果没有,有人可以指出我在Java SE 6源代码中的某个位置,在那里我可以看到所存储的Windows凭据不能被忽略吗?
Update: If not, could someone point me to a place in the Java SE 6 source code where I can see that the stored Windows credentials cannot be ignored?
推荐答案
我一直在寻找与您要求相同的内容.到目前为止,我还没有在JDK上找到实现此目的的方法.
I've looked for the same thing you are asking. So far, I haven't found a way on the JDK to do that.
有一个关于Java Bug数据库的增强请求.查看报告,以了解是否得到了响应Sun(表决报告,希望可以尽快解决.)
There is a request for enhancement on Java Bug Database. Take a look at the report to find out if that gets a response from Sun (vote up the report so that hopefully that gets fixed soon).
我最终要做的是重写sun.net.www.protocol.http.NTLMAuthentication
类.通过查看sun.net.www.protocol.http.HttpURLAuthentication
,我发现您需要修改的唯一内容是:
What I ended up doing, was override sun.net.www.protocol.http.NTLMAuthentication
class. By looking at sun.net.www.protocol.http.HttpURLAuthentication
, I found that the only thing you need to modify is the result of:
NTLMAuthentication.supportsTransparentAuth()
该方法具有硬编码的返回值,在Windows平台上为true
,否则为false
.此代码是从Windows 7上安装的JDK中提取的:
That method has a hardcoded return value, true
on Windows platforms and false
otherwise. This code is extracted from a JDK installed on Windows 7:
static boolean supportsTransparentAuth()
{
return true;
}
该方法说明的是默认情况下是否应使用Windows凭据.如果设置为true
,则您的自定义身份验证器代码将不会被调用.请参见HttpURLConnection
类的以下片段:
What that method tells is if Windows credentials should be used by default. If set to true
, your custom Authenticator code won't be called. See this fragment of HttpURLConnection
class:
//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,并复制所需的类代码.
To get NTLMAuthentication
source code, I used this Java decompiler. Opened rt.jar located on the JDK installation folder and copied the desired class code.
然后,我简单地更改了supportsTransparentAuth
以返回false.但是,如果此方法首先检查系统属性,然后根据该属性返回true或false,则将是非常可取的.
Then, I simply changed supportsTransparentAuth
to return false. However, it would be highly desirable if this method checked first a system property and then return true or false based on that.
要编译它,我只是将java文件放在sun/net/www/protocol/http文件夹结构下并运行:
To compile it, I just placed the java file under sun/net/www/protocol/http folder structure and run:
javac NTLMAuthentication.java
然后使用以下命令运行我的应用程序:
Then run my application using:
java -Xbootclasspath:"path/to/your/sun/net/www/protocol/http/classes;normal/JDK/boot/directories"
这将告诉JVM在rt.jar中的NTLMAuthentication
实现之前加载我们的实现.您必须小心,不要错过任何带有-Xbootclasspath
的默认类加载路径,否则会出现ClassNotFound
错误.
That will tell the JVM to load our implementation of NTLMAuthentication
before the one in rt.jar. You have to be careful to don't miss any default class loading paths with -Xbootclasspath
, or there will be ClassNotFound
errors.
之后,一切都很好.
此方法具有应注意的重要缺点.
This approach has important drawbacks that you should be aware of.
- 存在安全风险.任何人都可以将其他.class文件拖放到启动文件夹中,并窃取用户凭据或其他重要信息.
- Sun软件包中的代码可能会更改,恕不另行通知,因此与您的更改不兼容.
- 如果部署此代码,则将违反Sun代码许可证.从文档:
-Xbootclasspath:bootclasspath指定用分号分隔的目录,JAR存档和ZIP存档列表以搜索引导类 文件.这些文件代替了包含在其中的引导类文件. Java 2 SDK.注意:出于以下目的使用此选项的应用程序: 不应部署覆盖rt.jar中的类,因为这样做会 违反了Java 2 Runtime Environment二进制代码许可证.
-Xbootclasspath:bootclasspath Specify a semicolon-separated list of directories, JAR archives, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java 2 SDK. Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.
因此,这绝对不适合生产环境.
So, this is definitely not suitable for production environments.
Finally, this is an excellent source about boot class path option and Java class loaders: PDF
希望这会有所帮助.
这篇关于是否可以在Windows上禁用Java的“单点登录"(使用“凭据管理器"中的凭据)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!