TL; DR:看看 这个和那个样本解决方案。
您所要求的取决于您使用的特定于供应商的功能所提供的灵活性。您的产品可能会也可能不会允许您扩展那个/这些
LoginModule//
Realm/
的行为,
IdentityStore无论它是什么/被称为专有类,甚至可能只是在某些管理UI的输入字段中键入SQL查询。最重要的是,它是非标准功能。
在标准Java EE方面,有 JASPIC (用户/消息身份验证)和 JACC
(授权)SPI。两者都可用于从某些外部存储中检索与您的用户有关的安全性相关信息。JASPIC不能做的就是 在 验证 后
更改用户的角色;也就是说,在经过 身份验证的请求 1的持续时间内,用户的角色是 固定的 。JASPIC也不能赋予这些角色以 含义
;因为它们仅仅
String是AS将以某种专有方式派生group
Principal的原因。另一方面,JACC可以做这些事情,因为它建立了“规则库”(认为
Policy),它将角色,主体和
Permissions精确地关联起来,并且可以在每次用户与系统的每次交互中查询。JACC还可以覆盖或更改对通过部署描述符和批注表示的Java
EE安全约束的解释。
我将在这篇文章中包括一个基于JASPIC的解决方案,而在很大程度上忽略了JACC,因为:
- 您可能不需要JACC提供的其他灵活性。
- 使用定制JACC提供解决方案需要相当 一点 的工作,但仍未100%的标准,由于AS-特定组到角色映射。
- 我没有意识到使用定制的JACC提供程序来完成有意义的事情的开源项目。唯一的例外是Java EE完整概要文件实现AS,因为它们被要求实施规范,有时还在内部使用其JACC提供程序(例如,对于GlassFish)。
- 围绕JASPIC仍然有很多困惑(许多开发人员都不知道它甚至存在),这是两个规范中最简单的一种。在继续讨论JACC之前,首先让JASPIC广为人知并“吸引”更多人是不合理的。
- 尽管现在在线上JASPIC上的例子不只少数,通过JASPIC提供程序实现实际身份验证的项目也是如此,-如果我弄错了,请更正我-在SO上还没有找到完整的JASPIC示例。
关于以下内容的一些评论:
- 如果您的应用程序/ AS /系统爆炸或被外星人/等入侵,则不提供任何担保/使用风险自负/不起诉我。
- 请,请忽略那些您认为最重要的方面,即优化,更好的设计或其他改进。是的,您可以承认可以重复使用DB / LDAP连接;验证插入LDAP搜索过滤器中的用户名;更关心线程安全;使用TLS; 对于格式不正确的XML有效载荷,返回400。解决这些问题不在提供的解决方案的范围内。对不起??您想知道 单元测试 在哪里吗?对不起,没听说过这个词!:)
- 提供了两个具体执行组和角色(角色)身份验证和检索的SAM:一个“独立”功能,它可以独立完成两项任务;一个“委派”功能,其名称表明,它演示了SAM如何委派实际身份验证
LoginModule
通过使用JASPIC LoginModule桥概要文件 ,可以工作于JAAS (LM)。后者SAM需要在AS和本身在源级别进行进一步的配置/调整,除非您使用的是GlassFish。提供了随附的示例JAASlogin.conf
条目。 - 提供程序类已针对GlassFish 4.1进行了测试。他们努力保持符合规范,因此,如果您的产品实现了Full Java EE(6,最好是7)配置文件,那么它们也应该在您的AS上也确实可以工作(显然,第二个SAM除外)。如果没有,我很抱歉;不,我不会在您的AS上进行测试。
- 您可以避免研究/使用
AuthConfigProvider
和ServerAuthConfig
实现,但是随后将必须以AuthConfigFactory
专有方式(通过特定于供应商foo-web.xml
和/或进一步使用部署/管理工具)在产品中注册实际SAM 。此外,您将没有SAM实现该ServerAuthContext
接口,并且必须Properties
从SAM中加载随附文件。然后,您的AS将为您实例化缺少的类,可能会重用“全局”AuthConfigProvider
和/或ServerAuthConfig
为所有应用程序和消息层进行了预配置。请注意,取决于它是否重用其实例化的请求ServerAuthConfig
和ServerAuthContext
跨请求的请求(几乎没有发生,尤其是后者),SAM的生命周期可能会受到影响。 - 由于特定于容器,因此未涵盖组到角色的映射。
- 我想在任何地方添加评论。并非所有(全部)都没有用。在规范的帮助下,代码应该易于理解-但请随时询问是否有问题困扰您。对于过长的帖子表示歉意。
- 从标准Maven项目的根开始,路径是绝对的。适应SAM中的属性和/或身份验证/组检索方法后,您可以将所有文件构建为WAR,然后将其按原样部署在AS上进行测试。唯一的依赖关系是(
provided
)javaee-api
7.0(加上JDBC驱动程序,除非AS类路径上已经存在)。 - 由于SO的帖子长度限制,我不得不将代码移至Gist。
- 正在
ServletContextListener
注册AuthConfigProvider
。另存为/<project>/src/main/java/org/my/foosoft/authn/BigJaspicFactoryRegistrar.java
。 - 的
AuthConfigProvider
。另存为/<project>/src/main/java/org/my/foosoft/authn/BigJaspicFactory.java
。 - 的
ServerAuthConfig
。另存为/<project>/src/main/java/org/my/foosoft/authn/LittleJaspicServerFactory.java
。 - 基本的双重
ServerAuthContext
-ServerAuthModule
实现帮助程序类。这是实际答案的1/3。另存为/<project>/src/main/java/org/my/foosoft/authn/HttpServletSam.java
。 - 该独立SAM执行。实际答案,第2/3部分。另存为
/<project>/src/main/java/org/my/foosoft/authn/StandaloneLdapSam.java
。 - 该JAAS LM-SAM委托。实际答案,第3/3部分。另存为
/<project>/src/main/java/org/my/foosoft/authn/JaasDelegatingLdapSam.java
。 - 便利例外类型。另存为
/<project>/src/main/java/org/my/foosoft/authn/JaspicMischief.java
。 - 随行的
Properties
。如果您想逐字测试实际的身份验证代码,请使其适应您的需求。另存为/<project>/src/main/resources/org/my/foosoft/authn/jaspic-provider.properties
。 - (6)的随附示例
login.conf
代码段;有关实际文件系统位置,请参阅供应商的文档。 /<project>/src/main/java/org/my/foosoft/presentation/UserUtils.java
(可选-出于演示目的:JSF支持bean)/<project>/src/main/webapp/index.xhtml
(可选-出于演示目的:未受保护的索引页)/<project>/src/main/webapp/login.xhtml
(可选-出于演示目的:登录页面)/<project>/src/main/webapp/restricted/info.xhtml
(可选-出于演示目的:角色用户的受保护索引页access_restricted_pages
)/<project>/src/main/webapp/WEB-INF/web.xml
(可选-出于演示目的和出于完整性的考虑:Web模块DD)
进一步阅读:
- JSR-196(JASPIC)规范
- Arjan Tijms的 JASPIC ZEEF页面
- JSR-115(JACC)规范
1 JASPIC是非常通用的SPI,从理论上讲,当插入有能力的消息处理运行时时,它就可以对JMS,SAML-over-
SOAP和任何其他类型的消息进行身份验证。即使它主要用于 Servlet容器配置文件, 也不会过度限制它。
JASPIC的低级别,灵活的特性使您不了解特定于协议的功能,例如HTTP会话。因此,
ServerAuthContext运行时将触发s /
SAM,以对每个请求执行身份验证。
但是,该规范通过允许SAM 通过运行时通过 Callback属性 请求发起 容器身份验证会话
来对此潜在的缺陷作了规定。当要求对同一客户端的后续请求进行身份验证时,SAM可以通过要求运行时重用先前建立的AS身份验证会话,从而避免用户身份(调用方和/或组)重用,从而避免重复整个过程。这是通过执行示例代码的中所示的“不做/离开身份验证状态为协议”来完成的。
MessageInfo
__
Principal``HttpServletSam
最后应该指出的是,JASPIC和Servlet规范都没有明确定义什么是 容器认证会话
。对于SAM身份验证的用户,出于所有实际目的,我将认为AS身份验证会话与HTTP会话等效,只要a)身份验证涉及单个应用程序上下文,b)SAM,如上所述,表示在每个请求上重复使用AS身份验证会话。



