您是集成现有应用程序,还是只想支持自己的应用程序?
您是在寻找实际的 SSO 还是只是共享凭据?SSO 是登录到单个应用程序,并将该凭据传播到另一个应用程序(例如登录到 Gmail 并自动登录到 Blogger)。共享凭据是,您可以跨应用程序使用相同的登录名和密码,但凭据本身不会自动传播。
LDAP 是用于管理共享凭证的通用系统。许多系统允许您将其身份验证存储指向现有的 LDAP 服务器。
例如,如果您在Java EE容器中部署了多个应用程序,并且还部署了电子邮件服务器和基于Web的电子邮件客户端,则所有这些不同的应用程序都可以指向同一个LDAP服务器,并且您的用户将具有所有不同系统的单个登录名和密码,所有这些系统都是用不同的语言编写的。 全部部署在不同的计算机上。这是LDAP的面包和黄油用例,几乎每个系统都可以开箱即用地处理这个问题。Glassfish和Tomcat都可以很容易地针对LDAP服务器进行验证。Apache(Web服务器),Postgres(数据库),Postfix(电子邮件)等也可以。
因此,如果您只需要一个共享凭据,则可以通过安装LDAP服务器立即“免费”获得该凭据。LDAP与DBMS之类的东西有点不同,但是一旦你稍微研究一下它并“得到它”,它真的非常好。OpenLDAP是一个流行的LDAP服务器,但我偏爱ApacheDS。
在 Java EE 容器中设置它的方法是设置一个“Realm”。GF和Tomcat都有开箱即用的LDAP领域,我想其余的都是如此。但关键是,你需要使用Java EE安全性来利用Realm。
看,Java EE Realm 的细节是它是 CONTAINER 的一个方面,而不是应用程序的一个方面。就像连接池是应用程序利用的容器资源一样。大多数人都希望安全性成为其应用程序的一部分,他们觉得自己可以更好地控制它。
这一切都很好,直到你开始获得一堆不同的应用程序,每个人都有不同的配置,有单独的用户列表,密码策略等。
LDAP可以修复很多问题,因为您将它们全部配置为使用相同的凭据存储。
Realm 在 Java EE 服务器上满足了这一需求。您的应用程序被配置为使用容器提供的 Realm 数据库。如果您有多个应用程序和一个 Realm 数据库,那么它们都可以在该 Realm 领域内共享凭证(无论 Realm 类型如何)。
领域可以是任何东西:基于文件,基于数据库,LDAP等。领域也集群,如果容器集群(这可能很方便)。
Java EE安全性的阴暗面,以及大多数应用程序避免使用它的原因在于,由于Realm是容器的一部分,而不是应用程序的一部分,因此使用起来可能有点笨拙,并且可能无法提供您在用户管理,密码策略等方面喜欢的功能。
但是Java EE安全性的亮点在于,一旦你掌握了它的保护伞,你就可以很容易地在代码中利用这个凭证。一个人登录到网站,该凭据可以在 Web 应用程序中使用,或者自动传播回 EJB 层(曾经是远程 EJB 层),并且信息始终很方便。
你可以将你的 Web 应用程序指向一个领域,你 EJB,你的 Web 服务。他们都利用相同的部分。
为了获得两全其美的优势,需要利用特定于容器的机制来访问容器安全性。这是Java EE安全性的另一个阴暗面。
像 Realms 这样的东西,以及对容器安全性的直接访问,不能跨容器移植。GF与Tomcat不同,与WebLogic不同。这一切都非常接近,但在细节上有所不同,因此您的代码不会无缝移植。
好的一面是内部应用程序,大多数人只是利用他们拥有的容器,围绕容器依赖代码进行合理的抽象,并称之为day,并指出是的,如果他们移动到另一个容器,他们将不得不移植它。但是,在实践中。就像数据库一样,一旦选择了容器平台,人们往往会紧紧地依偎在一起并坚持下去。
最后,Servlet 3.0(在GF3和Tomcat 7中)标准化了更多的编程登录问题,使它们在容器之间更具可移植性,但基本概念是相同的。
现在,SSO。
SSO是一个不同的野兽。但是,从本质上讲,GF和Tomcat都支持Web应用程序的SSO。这使您可以登录到一个Web应用程序,并能够轻松访问其他应用程序,而无需登录它们。但是SSO有点受限,因为它更依赖于容器安全性和生命周期,而不是在应用程序控制下更灵活的容器安全性和生命周期。请注意,不仅仅是在 Realms 上(这是给定的),而是在实际的基于容器的 FORM 登录上,而不是自定义编程登录上。FORM登录并不壮观,但它是功能性的,它的工作原理。实现一个 Realm,将你的应用程序部署到 Tomcat 或 GF 的单个实例(或 GF 3.1 中的集群),然后你就可以免费获得 SSO,所以如果这很重要,那真是太好了。它的可用性对于后台应用程序来说很好,但对于公共互联网来说可能不是。
如果你想要一个更复杂的 SSO 解决方案,那么你需要看看自定义实现。OpenSSO就是其中之一,它依赖于SAML和SAML Web配置文件。但是,还有其他一些。还有 CAS、Atlassian Cloud、Kerberos 和 OAuth。这些都使用与SAML不同的协议。如果你想坚持使用SAML,你也可以看看Shibboleth,甚至SimpleSAML(SimpleSAML是一个PHP服务器,充当SAML身份提供者,除其他外,但你仍然需要一个服务提供者在你的应用程序中)。
无论您选择哪种协议,该过程基本上都是相同的(此处详细介绍 - 跨域登录 - 如何在从一个域转移到另一个域时自动登录用户)。
但魔鬼在细节中。而且,孩子,有魔鬼吗?
所有这些系统都很复杂。单点登录很复杂。例如,现在你有单一登录,那么单一注销呢?单次超时呢?用户登录时的凭据更改会怎样?Web 服务的 STS(安全令牌服务)怎么样?(STS 为 Web 服务提供了类似的委派身份验证机制。
SAML 向您介绍了大量新词汇和许多配置。它不容易被拾起,因为文档不是一流的,并且在很大程度上依赖于标准文档,这些文档与更高级别的通用内容进行通信,而不是专门针对您和您的应用程序。
如果您不需要真正需要SSO,那么您可能会对中央LDAP存储之类的东西感到满意,并从那里继续。
总而言之,例如,我们的应用程序同时支持数据库和LDAP后端。他们使用Glassfish和Java EE安全性。我们完全控制用户体验。我们还通过 SAML 支持 SSO(我们编写了自己的身份和服务提供商),并且使用我们的代码和第三方代码,通过 JAVA 和其他应用程序的 LDAP 和 SSO 共享凭据。好的一面是,这是所有基于标准的。黑暗的一面是,标准是用英语传达的,英语是可以解释的。
我这样说只是为了说这是可以做到的。我还使用简单的Servlet过滤器编写了ad hoc,在餐巾纸SSO实现的后面,相同的域和跨域(同一域对于共享cookie来说很简单)。密码策略,密码恢复,保持活动计时器,多窗口超时和会话管理(这是一个骗局),角色,权限等。去过那里,做过。
另外,我不能不提到Spring和Spring Security,它们在Spring之上提供了所有这些。我没有用过它(我不是Spring的人),但那些人确实知道他们在做什么,所以值得一看。