加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Windows上的Java的“单一登录”(使用来自“凭据管理器”的凭据)

发布时间:2020-12-13 20:15:16 所属栏目:Windows 来源:网络整理
导读:来自 Java SE 6文档的Oracle的 “Http Authentication”页面说,“如果您在Windows机器上作为域用户运行,或者您正在已经发出kinit命令并获得凭据缓存的Linux或Solaris计算机上运行”,那么传递给 Authenticator.setDefault() 的实例将被完全忽视“. 这与我观察
来自 Java SE 6文档的Oracle的 “Http Authentication”页面说,“如果您在Windows机器上作为域用户运行,或者您正在已经发出kinit命令并获得凭据缓存的Linux或Solaris计算机上运行”,那么传递给 Authenticator.setDefault()的实例将被完全忽视“.

这与我观察到的一致:在Windows系统上设置主机X的HTTP或HTTPS连接总是从“Windows Vault”的“Windows凭据”传递主机X的凭据,如我的Windows 7“凭据管理器”控制面板页面.

但是,在我的用例中,我不想使用Windows可能存储的任何凭据,而是总是希望使用我在代码中明确指定的凭据.

有没有办法来覆盖记录的行为,即有没有办法忽略Windows存储的凭据?

更新:如果没有,有人可以指出我在Java SE 6源代码中的一个地方,我可以看到存储的Windows凭据不能被忽略?

我找到了你所要求的同样的事情.到目前为止,我还没有找到JDK这样做的方法.

有一个Java Bug数据库增强的请求.看看report,看看是否从Sun获得回应(投票支持报告,希望能够很快得到修正).

我最终做的是覆盖sun.net.www.protocol.http.NTLMAuthentication类.通过查看sun.net.www.protocol.http.HttpURLAuthentication,我发现你唯一需要修改的是以下结果:

NTLMAuthentication.supportsTransparentAuth()

该方法具有硬编码的返回值,在Windows平台上为true,否则为false.此代码是从安装在Windows 7上的JDK中提取的:

static boolean supportsTransparentAuth()
{
  return true;
}

该方法告诉的是,默认情况下应该使用Windows凭据.如果设置为true,则不会调用您的自定义验证码.看到这个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源代码,我使用了this Java decompiler.打开的rt.jar位于JDK安装文件夹中并复制了所需的类代码.

然后,我简单地更改了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"

这将告诉JVM在rt.jar之前加载NTLMAuthentication的实现.你必须小心,不要错过任何使用-Xbootclasspath的默认类加载路径,否则会出现ClassNotFound错误.

之后,一切工作都很好.

这种方法有重要的缺点,你应该注意.

>有安全隐患任何人都可以在您的引导文件夹中放置不同的.class文件,并窃取用户凭据或其他重要信息.
> Sun软件包的代码可以更改,恕不另行通知,因此与您的更改不兼容.
>如果您部署此代码,则会违反Sun代码许可.从documentation:

-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.

所以这绝对不适合生产环境.

最后,这是一个引导类路径选项和Java类加载器的优秀源:PDF

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读