是否可以在Windows上禁用Java的“单点登录"(使用“凭据管理器"中的凭据)? [英] Can Java's 'single sign-on' (use credentials from 'Credential Manager') on Windows be disabled?

查看:176
本文介绍了是否可以在Windows上禁用Java的“单点登录"(使用“凭据管理器"中的凭据)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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.

最后,这是有关引导类路径选项和Java类加载器的绝佳信息:

Finally, this is an excellent source about boot class path option and Java class loaders: PDF

希望这会有所帮助.

这篇关于是否可以在Windows上禁用Java的“单点登录"(使用“凭据管理器"中的凭据)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆