在 Java 或命令行工具中,有没有办法使用本机 SSPI API 获取服务的 Kerberos 票证?

我想在Java中实现使用Kerberos的单一登录,并已成功设法使用Windows登录中的票证为服务创建票证。不幸的是,我只能在注册表项“allowtgtsessionkey”启用时创建该票证。我收到一个异常,其中包含消息“标识符与预期值 (906)不匹配”,只要我禁用它。注册表项记录在 http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.htmlhttp://support.microsoft.com/kb/308339 上。

不幸的是,我无法访问将使用我的应用程序的计算机上的注册表,因此我正在寻找一种方法来执行此操作,而无需对其进行修改。当我在Internet Explorer或Mozilla Firefox中通过SPNEGO进行单点登录时,他们会在我的票证缓存中创建一个服务票证,因此肯定必须有一种方法可以在不设置注册表项的情况下执行此操作。有没有人知道如何在Java中做到这一点?

感谢您的帮助,梅明格

更新:我放弃了这个问题。Windows 注册表项阻止访问票证缓存中的票证(更准确地说:主题)。Windows上的Java使用自己的GSSAPI实现,我认为需要访问票证才能创建服务票证。不过,SSPI Windows API 具有对票证缓存的完全访问权限,因此可以创建服务票证。此 API 由 Web 浏览器使用,但未被 Java 使用(根据 http://java.sun.com/developer/technicalArticles/J2SE/security/#3)。当我在访问一个网页一次后在Firefox中禁用SSPI时(因此已经创建了一个服务票证),我仍然可以访问该页面,所以也许命令行实用程序就足够了,可以使用SPPI API创建服务票证。

对于我们来说,这意味着现在我们可以放弃单一登录(这对我们来说是不可接受的),或者我们在应用程序的客户端进行身份验证(因为我们只能读出用户名,但不能验证服务器上的票证),这是一个主要的安全风险。另一个例子是,更强的安全约束如何导致更大的安全漏洞,因为它们变得太复杂而无法使用。


答案 1

原谅我,如果我误解了你的问题,但是...

SSO 类型系统的要点是客户端直接向(单独的)身份验证服务器进行身份验证,并从中获取票证。然后,它将票证传递给它要使用的目标服务器,每个服务器都验证票证在身份验证服务器上是否有效。如果票证已验证,则服务器可以假定客户端仅通过向(受信任的)Kerberos 服务器提供可接受的凭据来获取票证。

在此过程中,任何服务器都不应代表客户端进行身份验证。在这样的系统中,唯一需要知道和验证客户端凭据的服务器是身份验证服务器 - 没有其他服务器需要访问此信息。这样,客户端只需一个身份验证交换即可对许多服务器进行身份验证,并且凭据不会因存储在多个服务器上或可供多个服务器访问而面临风险。

听起来您的实现正在正常工作 - 身份验证应该在应用程序的客户端进行,这是正确的,而不是安全风险。


答案 2

你有没有试过在Java 6中设置sun.security.jgss.native?SSPI不是Windows的“原生”接口吗?


推荐