GSSAPI缺陷门票

时间:2016-12-22 00:46:46

标签: java iis kerberos gssapi

我很抱歉,如果有一些事情真的很直接我错了 - 我发现很难找到有关GSSAPI和JAAS的更多信息。

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

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

从我的机器上,我运行了一个使用GSSAPI和JAAS进行身份验证的程序。它基于the Oracle tutorials for GSSAPI非常重要,因为在这个阶段,我只是试图理解它。它使用KrbLoginModule登录,根据域中某些给定的测试用户创建主题,这些用户似乎都运行正常。在网络跟踪中,我的机器和域控制器之间有一个AS-REQ,AS-REP,TGS-REQ和TGS-REP(如果我正确的话,它应该是这样) VM。

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

我最初在上下文循环中完成了它在教程中的完成情况(上面已链接),但当它尝试从服务器开始读取令牌时(即token = new byte[inStream.readInt()];){{1}读取它是巨大的(1213486160,我检查它几次 - 似乎每次都是这样)。这导致OutOfMemoryError。

然后我开始使用" Stream版本"采用输入和输出流的initSecContext(我给出了我打开服务器的套接字的输入/输出流 - 我假设它是它想要的)。这开始看起来效果很好。它建立了一次迭代,但是当你尝试打包/解包消息时,事情又开始出错了。当您尝试解包消息时,它会引发错误:

length

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

然后是HTTP响应。这是400 Bad Request。在回复的主体中,它说它是一个无效的动词(我假设当它说动词时它意味着" GET"或者" POST等是这样吗?)。跟踪还指出它是对第一条TCP消息的确认。通过一些谷歌搜索,我发现了a guy who had a similar problem。事实证明,这是关于一个防病毒软件正在发送请求的标题(可能它与重定向有关?)。

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

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

更新

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

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

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

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

更新

如前所述,当我使用initSecContext读取令牌时,我希望根据教程首先考虑长度(即General failure, unspecified at GSSAPI level minor string: Error in method wrap, error: java.net.SocketException: Unrecognized Windows Sockets error: 0: socket write error )。我得到的是1213486160,它导致了OutOfMemoryError。但我意识到,1213486160是0x48545450,在ASCII中,它是" HTTP"。所以我读了下一堆字符和"响应标记"是HTTP 400 Bad Request。

这使我怀疑我是否应该读取整数,如教程中所示。我觉得这个问题有些不同,所以我做了new question here。这可能不是问题(比如,不是因为它导致它发送"错误请求"首先),所以我现在暂时保持这个问题。

另一个更新:

所以我查看了token = new byte[inStream.readInt()];吐出的令牌并编码到Base64,它的YII ......(即谈判令牌)。

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

这告诉我,我不需要执行建立上下文步骤(至少,正如教程中所示),或者我需要抓取令牌并将其发送到HTTP请求而不是直接的TCP消息。是否有任何人(或任何人的例子 - 我似乎无法找到任何人)使用GSSAPI / Kerberos对可以确认此问题的IIS进行身份验证?

2 个答案:

答案 0 :(得分:1)

确保客户端计算机已加入与IIS服务器相同的Active Directory域,以便Kerberos身份验证正常工作。 "令牌瑕疵"通常意味着客户端计算机在服务器需要Kerberos时发送了NTLM身份验证令牌。有这种不良行为发生的原因。

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

答案 1 :(得分:0)

所以有几件事需要检查。 首先要确保@ T-Heron所说的内容得到验证。如果这些仍然不起作用,请考虑以下事项:

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