我想在Java中使用Kerberos实现单点登录,并且已成功设法使用Windows登录中的票证为服务创建票证.不幸的是,我只能在启用注册表项"allowtgtsessionkey"时创建该票证.一旦禁用它,我收到一条消息"标识符与预期值不匹配(906)".注册表项记录在http://java.sun.com/j2se/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.html和http://support.microsoft.com/kb/308339上.
不幸的是,我无法访问将使用我的应用程序的计算机上的注册表,因此我正在寻找一种方法来执行此操作而无需修改它.当我在Internet Explorer或Mozilla Firefox中通过SPNEGO进行单点登录时,他们会在我的票证缓存中创建一个服务票证,因此必须有一种方法可以在不设置注册表键的情况下执行此操作.有没有人知道如何用Java做到这一点?
感谢您的帮助,memminger
更新:我放弃了这个问题.Windows注册表项阻止访问故障单缓存中的故障单(更准确地说:主题).Windows上的Java使用自己的GSSAPI实现,我认为需要访问Ticket才能创建Service Ticket.但是,SSPI Windows API具有对票证缓存的完全访问权限,因此可以创建服务票证.Web浏览器使用此API,但Java不使用它(根据http://java.sun.com/developer/technicalArticles/J2SE/security/#3).当我在访问网页一次后禁用了Firefox中的SSPI(因此创建了服务票证)时,我仍然可以访问该页面,因此使用SPPI API创建服务票证可能足以使用命令行工具.
对我们来说,这意味着我们现在可以放弃单点登录(这对我们来说是不可接受的),或者我们在应用程序的客户端进行身份验证(因为我们只能读出用户名但不能验证机票上的服务器),这是一个主要的安全风险.另一个例子是安全性限制如何导致更大的安全漏洞,因为它们变得太复杂而无法使用.
我们正在使用JAAS在使用Windows Kerberos票证缓存的Java应用程序中启用单点登录.我们的jaas.conf配置文件如下所示:
LoginJaas {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true
doNotPrompt=true
debug=true;
};
Run Code Online (Sandbox Code Playgroud)
有了这个,我们可以创建一个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,它只包含服务器票证名称和域,因此不适合验证.
感谢您的帮助,memminger
我正在尝试在 Visual C++ 2008 Express Edition 中编译具有 SSPI 支持的 mod_spnego ( http://sourceforge.net/projects/modgssapache/ )。我已经设法让编译本身工作正常,但现在我遇到了链接器打印出的一些错误:
正在链接...创建库 2-win32-debug/mod_spnego.lib 和对象 2-win32-debug/mod_spnego.exp mod_spnego.obj :错误 LNK2019:函数 _handleSpnegoTokenSSPI mod_spnego.obj 中引用的无法解析的外部符号 __imp__DeleteSecurityContext@4 :错误 LNK2019:函数 _handleSpnegoTokenSSPI mod_spnego.obj 中引用了无法解析的外部符号 _QueryContextAttributesA@12:错误 LNK2019:函数 _handleSpnegoTokenSSPI 中引用了无法解析的外部符号 _FreeContextBuffer@4 mod_spnego.obj:错误 LNK2019:函数 _handleSpnegoTokenS 中引用了无法解析的外部符号 __imp__AcceptSecurityContext@36 SPI mod_spnego.obj:错误 LNK2019 :函数 _handleSpnegoTokenSSPI 2-win32-debug/mod_spnego.so 中引用的无法解析的外部符号 _AcquireCredentialsHandleA@36 :致命错误 LNK1120:5 个无法解析的外部
查看源代码,这些方法来自于Microsoft SDK中的Sspi.h。我不知道如何在 Windows 上编译东西,所以我有一个简单的问题:哪个 lib 文件包含 SSPI API?我必须链接哪一个?
顺便说一下,目前链接了以下库: kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
谢谢你,梅明格