如何在 Java 中针对服务器验证 Kerberos 票证?

发布于 2024-08-20 10:34:09 字数 1098 浏览 7 评论 0原文

我们使用 JAAS 在使用 Windows Kerberos 票证缓存的 Java 应用程序中启用单点登录。我们的 jaas.conf 配置文件如下所示:

LoginJaas {
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=true
  doNotPrompt=true
  debug=true;
};

通过这个,我们可以创建一个 Jaas LoginContext 并成功获取用户的 Kerberos 票证。我们使用 JMI 将此票证发送到服务器应用程序。但我们无法在服务器上验证 Kerberos 票证实际上是由我们的 Active Directory 创建的。

目前,我们通过简单地检查服务器主体 (KerberosTicket.getServer()) 名称是否在领域部分中有我们的域名来对票证进行非常不安全的验证。当然,任何人都可以使用相同的域名设置自己的 Kerberos 服务器,并使用该票证来启动应用程序。

我发现的一个想法是使用 Kerberos 票证针对 Active Directory LDAP 进行身份验证。不幸的是,我们使用 Windows 7 并重新使用 Kerberos 票证对 LDAP 进行身份验证仅在设置注册表项时有效(请参阅 http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.html,搜索allowtgtsessionkey)。这对于我们的用户来说是不可接受的。

有没有办法根据我们的 Active Directory 服务器验证票证?我怀疑有一种方法可以检查 KerberosTicket.getServer() 票证是否等于我们服务器的票证,但我不知道该怎么做。更新:KerberosTicket().getServer() 仅返回一个 KerberosPrincipal,其中只包含服务器票证名称和领域,因此它不适合验证。

感谢您的帮助, 梅明格

we are using JAAS to enable Single Sign On in a Java application using the Windows Kerberos ticket cache. Our jaas.conf config file looks like this:

LoginJaas {
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=true
  doNotPrompt=true
  debug=true;
};

With this, we can create a Jaas LoginContext and successfully get the user's Kerberos ticket. We send this ticket to out server application using JMI. What we don't manage to do though is to verify on the server that the Kerberos ticket was in fact created by our Active Directory.

At the moment, we do a very insecure validation of the ticket by simply checking if the Server Principal (KerberosTicket.getServer()) name has our domain name in the realm part. But of course, anyone could set up an own Kerberos server with the same realm name and use that ticket to start the application.

One idea I have found was to authenticate against the Active Directory LDAP using the Kerberos ticket. Unfortunately, we use Windows 7 and re-using the Kerberos ticket to authenticate against the LDAP only works when setting a Registry entry (see http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.html, search for allowtgtsessionkey). This is unacceptable for our users.

Is there any way to validate the ticket against our Active Directory server? I suspect there is a way to check if the KerberosTicket.getServer() ticket equals the ticket of our server, but I have no idea how to do that. UPDATE: KerberosTicket().getServer() only returns a KerberosPrincipal that contains nothing but the server ticket name and realm, so it is not suitable for validation.

Thanks for your help,
memminger

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无声无音无过去 2024-08-27 10:34:09

正如您所提到的,解决此问题的正确方法是对您的服务进行 Kerberos 化,这就是 Kerberos 协议的全部要点(根据服务器对客户端进行身份验证)。票证重用并不完全有效,因为如果这样做的话就会出现安全问题。
Kerberos 服务不需要“登录到 Active Directory”,它只需要与 AD 共享密钥。

顺便说一句,要使用 JAAS 获得 SSO 需要设置 allowedtgtsessionkey,在 Windows 上没有办法解决这个问题。

As you mentioned, the proper way to solve this is by kerberizing your service, which is the whole point of the Kerberos protocol (authenticating clients against servers). Ticket reuse doesn't work exactly because it'd be a security problem if it did.
A Kerberos service does not need to "log into Active Directory", it just needs to have a shared key with AD.

BTW, to get SSO using JAAS requires having that allowtgtsessionkey set, there's no way around that on Windows.

黑凤梨 2024-08-27 10:34:09

由于似乎没有人真正知道这个问题的答案,我想我们必须从我们的服务器应用程序中创建一个适当的 Kerberos 服务。登录到 Active Directory 本身并正确设置 ServicePrincipalName 属性的一种。有点像 SPNEGO 对 HTTP 的作用。一个很好的起点是 SourceForge 上的 SPNEGO Servlet 过滤器 (http://spnego.sourceforge.net/ )。 http://thejavamonkey.blogspot.com/2008/ 04/clientserver-hello-world-in-kerberos.html也是一个很好的关于如何进行服务登录的示例。
不幸的是,这会导致注册表项出现同样的问题,因此我在 Java 或命令行实用程序是否有办法使用本机 SSPI API 获取服务的 Kerberos 票证?

As no one seems to really know an answer to this, I suppose we have to make a proper Kerberos service out of our server application. One that logs in to the Active Directory itself and that has the ServicePrincipalName attribute set properly. Kind of like SPNEGO does for HTTP. A good starting point how to do that will be the SPNEGO Servlet filter on SourceForge (http://spnego.sourceforge.net/). http://thejavamonkey.blogspot.com/2008/04/clientserver-hello-world-in-kerberos.html is also a very good example of how to do Service logon.
Unfortunately, this leads to the same problem with the registry key, so I posted a new question on Is there a way in Java or a command-line util to obtain a Kerberos ticket for a service using the native SSPI API?.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文