有 3 种身份验证协议可用于在 Linux 或任何其他平台上执行 Java 和 Active Directory 之间的身份验证(这些协议不仅特定于 HTTP 服务):
Kerberos - Kerberos 提供单点登录 (SSO) 和委托,但 Web 服务器也需要 SPNEGO 支持才能通过 IE 接受 SSO。
NTLM - NTLM 通过 IE(和其他浏览器,如果配置正确)支持 SSO。
LDAP - LDAP 绑定可用于简单地验证帐户名和密码。
还有一种叫做“ADFS”的东西,它为使用调用 Windows SSP 的 SAML 的网站提供 SSO,因此实际上它基本上是使用上述其他协议之一的迂回方式。
每个协议都有其优势,但根据经验,为了获得最大的兼容性,您通常应该尝试“像 Windows 那样做”。那么Windows是做什么的呢?
首先,两台 Windows 机器之间的身份验证有利于 Kerberos,因为服务器不需要与 DC 通信,并且客户端可以缓存 Kerberos 票证,从而减少 DC 上的负载(并且因为 Kerberos 支持委派)。
但是,如果身份验证方都没有域帐户,或者如果客户端无法与 DC 通信,则需要 NTLM。所以 Kerberos 和 NTLM 不是互斥的,NTLM 也没有被 Kerberos 淘汰。事实上,在某些方面 NTLM 比 Kerberos 更好。请注意,当同时提到 Kerberos 和 NTLM 时,我还必须提到 SPENGO 和集成 Windows 身份验证 (IWA)。IWA 是一个简单的术语,基本上意味着 Kerberos 或 NTLM 或 SPNEGO 来协商 Kerberos 或 NTLM。
使用 LDAP 绑定作为验证凭据的一种方式效率不高,并且需要 SSL。但直到最近实现 Kerberos 和 NTLM 一直很困难,因此使用 LDAP 作为临时身份验证服务一直存在。但在这一点上,通常应该避免。LDAP 是信息目录,而不是身份验证服务。将其用于预期目的。
那么如何在 Java 中,尤其是在 Web 应用程序的上下文中实现 Kerberos 或 NTLM?
Quest Software 和 Centrify 等许多大公司都有专门提到 Java 的解决方案。我无法真正评论这些,因为它们是公司范围内的“身份管理解决方案”,因此,从他们网站上的营销宣传来看,很难准确地判断正在使用哪些协议以及如何使用。您需要与他们联系以获取详细信息。
在 Java 中实现 Kerberos 并不难,因为标准 Java 库通过 org.ietf.gssapi 类支持 Kerberos。然而,直到最近还存在一个主要障碍——IE 不发送原始 Kerberos 令牌,而是发送 SPNEGO 令牌。但是在 Java 6 中,已经实现了 SPNEGO。从理论上讲,您应该能够编写一些可以验证 IE 客户端的 GSSAPI 代码。但我还没有尝试过。多年来,Kerberos 的 Sun 实施一直是错误的喜剧,因此根据 Sun 在该领域的记录,我不会对他们的 SPENGO 实施做出任何承诺,除非您掌握了那只鸟。
对于 NTLM,有一个名为 JCIFS 的免费 OSS 项目,它具有 NTLM HTTP 身份验证 Servlet 过滤器。但是,它使用中间人方法来验证 SMB 服务器的凭据,该服务器不适用于 NTLMv2(这正在慢慢成为必需的域安全策略)。由于这个原因和其他原因,JCIFS 的 HTTP 过滤器部分计划被删除。请注意,有许多衍生产品使用 JCIFS 来实现相同的技术。因此,如果您看到其他声称支持 NTLM SSO 的项目,请查看细则。
使用 Active Directory 验证 NTLM 凭据的唯一正确方法是通过具有安全通道的 NETLOGON 使用 NetrLogonSamLogon DCERPC 调用。Java中是否存在这样的事情?是的。这里是:
http://www.ioplex.com/jespa.html
Jespa 是一个 100% Java NTLM 实现,支持 NTLMv2、NTLMv1、完整的完整性和机密性选项以及前面提到的 NETLOGON 凭据验证。它包括一个 HTTP SSO 过滤器、一个 JAAS LoginModule、HTTP 客户端、SASL 客户端和服务器(带有 JNDI 绑定)、用于创建自定义 NTLM 服务的通用“安全提供程序”等等。
麦克风