你是在整合现有应用程序,还是只想支持自己的应用程序?
你是寻找实际的单点登录(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容器中设置它的方法是设置一个“领域”。 GF和Tomcat都有LDAP领域,我想其余的也都有。 但其中的关键是,您需要使用Java EE安全性来利用Realm。
请注意,Java EE Realm的详细信息是它是CONTAINER的一个方面,而不是应用程序的一个方面。 就像连接池是应用程序利用的容器资源一样。 大多数人希望安全性成为其应用程序的一部分,这样他们感觉对其拥有更多控制权。
这很好,直到您开始获得许多不同的应用程序,并且每个人都配置不同,并且具有单独的用户列表、密码策略等等。
LDAP可以解决大部分问题,因为您可以将它们都配置为使用相同的凭据存储。
Realm可以是任何东西:基于文件、基于数据库、LDAP等。 如果容器集群,则领域也会集群(可能很方便)。
Java EE安全性的阴暗面,以及为什么大多数应用程序避免使用它,是因为再次提醒,领域是容器的一部分,而不是应用程序的一部分,因此在使用时可能有些笨拙,并且可能无法提供您喜欢的用户管理、密码策略等方面的功能。Java EE安全的好处是,一旦您使用它,就可以轻松地在代码中利用凭据。一个人登录网站,该凭证可以在Web应用程序中使用,或者自动传播回EJB层(甚至是远程EJB层),并且信息始终方便获取。您可以将Web应用程序指向领域(realm),您的EJB,您的Web服务。他们都可以共享同样的组件。
为了兼顾两个方面的优点,可以利用容器特定的机制来访问容器安全性。这是Java EE安全的另一面。
像领域和直接访问容器安全性等内容在不同的容器中不可移植。GF与Tomcat做法不同于WebLogic。尽管基本相似,但细节不同,因此您的代码可能无法无缝移植。
对于内部应用程序,大多数人只需利用已有的容器,在容器相关的代码周围放置合理的抽象层级,这样就可以解决问题了。但是,实际上,很多人会选择一个容器平台,并紧密合作并坚持下去,就像数据库一样。
最后,Servlet 3.0(在GF3和Tomcat 7中)标准化了更多的编程式登录问题,使其在不同容器中更易移植,但底层概念是相同的。
现在来谈谈SSO。
SSO是一个不同的问题。GF和Tomcat都支持Web应用程序的SSO,这使您可以登录到一个Web应用程序并能够轻松访问其他应用程序,而无需再次登录。但是SSO有些局限性,因为它更依赖于容器安全性及其生命周期,而不是受应用程序控制的更灵活的SAML和SAML Web Profile等自定义协议实现。如果您想要更复杂的SSO解决方案,则需要查看自定义实现。OpenSSO就是其中之一,它依赖于SAML和SAML Web Profile。还有其他选择,如CAS、Atlassian Cloud、Kerberos和OAuth等使用与SAML不同的协议。如果您要坚持使用SAML,则还可以查看Shibboleth,甚至是SimpleSAML(SimpleSAML是一个PHP服务器,可充当SAML身份提供者,但仍然需要应用程序中的服务提供者)。无论您选择哪种协议,流程基本相同(详见此处--
跨域登录 - 如何在从一个域转移时自动登录用户)。
但魔鬼就在细节中。而且,有很多魔鬼。
所有这些系统都很复杂。SSO也是复杂的。例如,现在你有了单点登录,那么单点注销怎么办?单点超时怎么办?当用户登录时凭证发生变化怎么办?Web服务的STS(安全令牌服务)怎么办?(STS为Web服务提供了类似的委托身份验证机制。)
SAML向您介绍了很多新词汇和大量配置。它不容易被掌握,因为文档并不十分出色,并且依赖于标准文档,这些文档对更高级别的通用事物进行了讲解,而不是专门针对您和您的应用程序。
如果您不需要真正的SSO,那么您可能会满意于像中央LDAP存储之类的东西,并从那里开始。
话虽如此,例如,我们的应用程序支持DB和LDAP后端。它们使用Glassfish和Java EE安全。我们完全控制用户体验。我们还通过SAML支持SSO(我们编写了自己的Identity和Service Providers),并且我们通过我们的代码和第三方代码支持LDAP共享凭据和Java和其他应用程序之间的SSO。好处是这都是基于标准的。不足之处在于,标准是用英语传达的,而英语是有解释的。
我这样说只是为了说明它可以做到。我还编写了即席的餐巾纸SSO实现,同域和跨域两种情况均适用(使用简单的Servlet过滤器可以实现同域)。密码策略、密码恢复、保持活动计时器、多窗口超时和会话管理(这真是个笑话)、角色、特权等等。经历过这些,做到过这些。
此外,我不得不提到Spring和Spring Security,它们在Spring之上提供了所有这些功能。我没有使用过它(我不是一个Spring人),但那些人确实知道他们在做什么,所以值得一看。