16

为了在 Windows 上使用 Java 进行客户端 HTTP SPNEGO 身份验证,您需要设置 Windows 注册表项allowtgtsessionkey。这是有据可查的。我不明白的是人们如何解决这个问题?大多数公司网站永远不会接受为了单个软件而在 Windows 中更改此注册表项。如果需要在组织中的每个工作站上进行更改,还要考虑一下麻烦。但这只是理论,因为到目前为止我无法说服我们的任何客户更改此注册表项。

我不怪他们。大多数公司管理员会认为这是一种放松安全措施,因此会反对。

我读过这篇文章: Java 或命令行实用程序中是否有办法使用本机 SSPI API 获取服务的 Kerberos 票证?

但它现在已经很旧了。

所以我真的,真的不明白人们如何让 Windows + Java 客户端 + Kerberos 在大学环境、家庭用户等之外的任何地方工作。

我从企业管理员那里得到的问题是“当 IE 和 Firefox 等应用程序在不设置此键的情况下执行 SPNEGO没有问题时,为什么我们需要设置此注册表键?”。嗯,我知道答案是什么。这是因为(很可能)IE 和 Firefox 等应用程序基于 Windows 原生 GSS API (SSPI),而 Sun 的 Java 使用自己的实现。

我假设使用类似WAFFLE的东西可以解决问题,但我更喜欢纯 Java 解决方案。我还假设使用基于 Java 的解决方案(例如 Spring security 或 Apache HttpClient)将无济于事,因为它们都会遇到这个问题。

任何帮助或指示将不胜感激。

更新1

我发现在 Oracle 的错误数据库中有一个RFE。Oracle 员工也提交了一个补丁,并在 JDK 邮件列表中讨论了这个特性。除了据我所知,这在当前的 Java 7 中是不可用的,甚至不是实验性的,这并没有让我变得更聪明。正确的?

更新2

这个问题现在在 OpenJDK 安全开发邮件列表中再次出现。

4

4 回答 4

10

感谢您在 security-dev 邮件列表中引用我的线程;-) 我的中期目标是通过认可的类路径使这个补丁可用于 Java 6+。您可能对我最近创建的这张 WAFFLE 票感兴趣:https ://github.com/dblock/waffle/issues/50

我也评估了 WAFFLE,但它不像 Java-GSS 那样必须创建重复的代码,这是我想尽一切办法避免的事情。

这整个问题并不完全是甲骨文的错。Microsoft 只是通过 LSACallPackage功能阻止对会话票证的任何调用。借口是安全。当我无法合理访问 TGT 时,我真的很想知道 SSPI 如何创建服务票证。因此,这样的封闭源解决方案很糟糕。

目前,您只有三个选择:

  1. 通过Java方式再次获取TGT
  2. 试试华夫饼
  3. 编写自定义代码

我已经埋葬了蹩脚的注册表项,因为它无论如何都不适用于具有域帐户的本地管理员。就我而言,Windows 上的 Tomcat 开发者同时调用了 Java 的 kinit。

于 2013-01-28T10:30:32.190 回答
1

对于使用 Java 8 寻找简单解决方案的人来说,Waffle是最佳选择。

代码:

import java.net.URI;
import java.util.Base64;

import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;

public class KerberosCredentiels {

  /**
   * Generate current user token using Kerberos ticket
   */
  public String retrieveToken(URI uri) {
    IWindowsSecurityContext clientContext = WindowsSecurityContextImpl.getCurrent("Kerberos", convertToSPN(uri));
    byte[] token = clientContext.getToken();

    return Base64.getEncoder().encodeToString(token);
  }

  private static String convertToSPN(URI uri) {
    StringBuilder builder = new StringBuilder();

    builder.append("http/");
    builder.append(uri.getHost());

    return builder.toString();
  }

}

Maven依赖:

<dependency>
    <groupId>com.github.waffle</groupId>
    <artifactId>waffle-jna</artifactId>
    <version>1.8.3</version>
</dependency>

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>4.3.0</version>
</dependency>

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.3.0</version>
</dependency>
于 2021-11-04T15:59:47.353 回答
1

现在 Apache HTTP 客户端中包含了一个非常好的解决方案,使用 JNA 从本机 SSPI API 获取票证。看到这个答案:

https://stackoverflow.com/a/22865583/381161

于 2015-10-02T14:57:42.347 回答
1

从 Java 13 开始,JDK 中现在为 Windows 自己的 GSS API(又名 SSPI)提供了内置支持。

请参阅Java 13 的发行说明以及JDK-6722928

更新: 现在已向后移植到 Java 11。您需要使用 Java 11.0.10 或更高版本。sspi_bridge.dll如果您的 JDK 发行版包含在目录中命名的文件,您可以识别它是否支持 SSPI bin

甚至还有向后移植到 Java 8 的门票,但截至 2021 年 11 月,它尚未实施。

于 2019-11-22T22:48:13.640 回答