【问题标题】:GSSAPI Defective TicketGSSAPI 有缺陷的票证
【发布时间】:2023-04-07 15:56:01
【问题描述】:

如果有什么直截了当的地方,我很抱歉,我对此有误 - 我发现很难找到有关 GSSAPI 和 JAAS 的大量信息。

我正在编写一个向 IIS 服务器发出请求并使用 Kerberos 进行身份验证的程序。

我有两个虚拟机:第一个是 Active Directory 域控制器。另一个正在运行 IIS 服务器。

在我的机器上,我正在运行一个使用 GSSAPI 和 JAAS 进行身份验证的程序。它很大程度上基于the Oracle tutorials for GSSAPI,因为在这个阶段,我只是想弄清楚它。它使用KrbLoginModule 登录,根据域中的某个给定测试用户创建主题,一切似乎都运行良好。在网络跟踪中,我的机器和域控制器 VM 之间存在一个 AS-REQ、AS-REP、TGS-REQ 和 TGS-REP(如果我没记错的话,应该是这样)。

然后我的程序使用上面生成的主题来运行一些主要基于code from the GSSAPI/JAAS tutorial 的 GSSAPI 代码。它创建名称/凭据/上下文没有任何错误,但是当它尝试建立上下文时,事情开始出错。

我最初是按照教程(上面链接)中的方式进行上下文循环,但是当它尝试开始从服务器读取令牌时(即token = new byte[inStream.readInt()];),它读取的length int 非常大(1213486160 ,我检查了几次-似乎每次都是这样)。这导致了 OutOfMemoryError。

然后我开始使用initSecContext 的“流版本”,它接受输入和输出流(我将我打开的套接字的输入/输出流提供给我的服务器 - 我假设这就是它想要的)。起初这似乎工作得很好。它建立了一次迭代,但是当您尝试打包/解包消息时,事情又开始出错了。当您尝试解包消息时,它会引发错误:

org.ietf.jgss.GSSException, major code: 10, minor code: 0
    major string: Defective token
    minor string: Bad token tag: 7284

为此的网络跟踪显示了一条与生成的令牌长度相同的 TCP 消息(我假设它是正在发送的包装令牌)。然后是 ICMP 重定向。我不确定这算不算什么,但我想我会提到它(我注意到它几乎包含了第一条 TCP 消息的全部内容)。

然后有一个 HTTP 响应。这是一个 400 错误请求。在响应的正文中,它说它是一个无效动词(我假设当它说动词时,它的意思是“GET”或“POST 等。是这种情况吗?)。跟踪还指出,这是对第一条 TCP 消息。经过一番谷歌搜索,我找到了a guy who had a similar problem。原来这是一个防病毒软件弄乱了正在发送的请求的标头(可能与重定向有关?)。

然后还有一些来自我的机器的 TCP 消息(连续三个)(它们包含我使用 wrap 方法在消息中发送的数据),然后是来自服务器的 length=0 TCP 确认。

所以我不确定它可能是什么(也许是重定向,但这似乎不太可能)。

更新:

我在另一个虚拟机上运行它(在同一个 Active Directory 域上),但它仍然收到 HTTP 400 错误请求响应。与以前不同的是,它现在肯定使用 Kerberos(上面是发送 NTLM 请求)。

网络跟踪显示 AS 和 TGS 请求和响应,然后发送票证。然后 IIS 服务器返回 400 Bad Request(同样是无效动词)。有一个细微的区别:Bad Request 响应不再是对正在发送的令牌的确认,尽管在 400 之前有一个空的 ack TCP 消息。

程序仍然认为它的上下文已经建立,但是如果你尝试包装一条消息,它会中断:

General failure, unspecified at GSSAPI level
    minor string: Error in method wrap, error: java.net.SocketException:
        Unrecognized Windows Sockets error: 0: socket write error

更新:

如前所述,当我使用 initSecContext 读取令牌时,我希望根据教程首先获得长度(即token = new byte[inStream.readInt()];)。我得到的是 1213486160,它导致了 OutOfMemoryError。不过,我意识到 1213486160 是 0x48545450,在 ASCII 中是“HTTP”。所以我读了下一堆字符,“响应令牌”是 HTTP 400 错误请求。

这让我怀疑我是否应该读取教程中所示长度的整数。我觉得这个问题有点不同,所以我做了一个new question here。不过,这可能不是问题(比如,首先不是导致它发送“错误请求”的原因),所以我暂时保留这个问题。

另一个更新:

所以我查看了由initSecContext 吐出并编码为 Base64 的令牌,它是 YII...(即协商令牌)。

当我通过 chrome 登录时,我还仔细查看了网络跟踪,在 AS 和 TGS 消息之后,它发送了一个 HTTP GET 请求,其标题行为 Authorization: Negotiate YII.....,与我的程序相反,它发送带有令牌长度的 TCP 消息,然后是令牌。

这表明我不需要执行建立上下文步骤(至少,如教程中所示),或者我需要获取令牌并将其以 HTTP 请求而不是直接发送TCP 消息。有没有人(或任何人的例子——我似乎真的找不到任何人)使用 GSSAPI/Kerberos 为 IIS 进行身份验证的人可以确认这一点?

【问题讨论】:

  • 我是刚刚对你的问题投了赞成票的人。很详细。现在我要问你:你说你有两个虚拟机:第一个是 Active Directory 域控制器,另一个是运行 IIS 服务器。只需在此处检查 - 您的客户端计算机是否也加入了此 Active Directory 域?必须是 Kerberos 身份验证才能工作。 “有缺陷的令牌”通常意味着客户端机器发送了一个 NTLM 身份验证令牌,而服务器想要一个 Kerberos 令牌。
  • 它不在同一个域中,但它当前正在使用域控制器作为其 DNS。我不确定这是否意味着什么,但是当我在 Chrome 中转到 IIS 服务器的“位置”时,它似乎使用了 Kerberos(所有 AS/TGS - REQ/REP 等等)。
  • 我刚刚再次检查了 Chrome,它正在使用 NTLM!也许我最近改变了一些东西 - 我一直在努力让它工作,并尝试了一堆不同的配置选项,然后当我让它工作时摆脱了一堆。我会说这可能是它。
  • 好的,我已经从属于该域的新 VM 运行它,并且错误消失了(我有一个新错误,但这是进步哈哈)!
  • 我明天再看看,现在东部标准时区对我来说已经很晚了。

标签: java iis kerberos gssapi


【解决方案1】:

确保客户端计算机与 IIS 服务器加入同一个 Active Directory 域,以便 Kerberos 身份验证正常工作。 “有缺陷的令牌”通常意味着客户端机器发送了一个 NTLM 身份验证令牌,而服务器需要一个 Kerberos 令牌。出现这种不良行为是有原因的。

  1. 如果客户端计算机不在同一个 AD 域中,则它必须在与 IIS 服务器域具有 2 向信任关系的域中。如果 AD 域位于同一林中,则默认情况下会发生这种情况。
  2. 必须配置从其他域访问 IIS 服务器的权限。摘要:如果这些问题的答案是,那么这就解释了为什么会发生基本身份验证回退。只有在 Kerberos 身份验证失败后才会尝试基本身份验证。

【讨论】:

    【解决方案2】:

    所以有几件事需要检查。 首先确保@T-Heron 所说的内容得到验证。如果这些是并且仍然无法正常工作,请考虑以下事项:

    1. 通过在 cmd 中使用命令 klist 来验证您是否获得了 kerberos 令牌。 (您应该会看到适合您的 IIS 主机的 HTTP/service.domain.com@DOMAIN.COM 条目)
    2. 确保 KDC 处于活动状态并且知道您请求的服务。
    3. 验证 IIS 知道它是服务主体
    4. 仔细检查您的 login.conf 和 krb5.conf(如果您以编程方式设置它们,则检查源代码中的这些部分)

    这是我找到的关于 Kerberos 的最佳答案,因此请务必查看:SO answer

    【讨论】:

    • 我运行了 klist,并且有一堆,所以我清除然后运行我的程序并且那里没有一个(或者在 Chrome 中访问它之后),但我肯定会超过一个网络,它肯定在使用 Kerberos(两者都有所有的 AS 和 TGS 消息)。 KDC 肯定是活动的(我们正在与它交谈)并且 IIS 应该知道它是谁(一切都设置好了 - 我们甚至在活动目录中确定了它)。我猜登录/krb 配置可能有问题。我必须仔细检查它们。
    • 进步很大。我不知道它是否必须在 kerberos 令牌的缓存中,因为它可以发送 not_cachable 或作为可转发的。这些文件的配置也让我有些紧张。由于我使用的是wildfly,我必须配置它运行的单个节点的配置,以便拥有一个带有我的jaas配置的安全域。 krb5.conf 作为 java 参数传递给我的应用程序。不过,这可以通过多种方式完成。
    猜你喜欢
    • 1970-01-01
    • 2017-07-31
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2012-12-30
    • 1970-01-01
    相关资源
    最近更新 更多