挂起容器请求LDAP用户角色的进程
在我的应用程序中,我使用基于表单的身份validation和LDAP-Realm。 对于授权,我使用数据库。 据我所知,这工作如下
App --> (user, pass) --> LDAP ask for security roles for 'user' --> JACC / Database <-- Administrator --
我可以挂钩我的应用程序调用的进程ask for security roles for 'user'
吗?
背景:
LDAP说: Okay, 'user' is authentified
数据库: give me all roles where username = user
现在我想自定义数据库查询: give me all roles where username = 'user' AND some more attributes
这有点可能吗?
TL; DR:看看这个和那个样本解决方案。
您要求的内容取决于您使用的供应商特定function提供的灵活程度; 您的产品可能会也可能不会允许您扩展该/ LoginModule
/ Realm
/ IdentityStore
/其他任何/他们所谓的专有类的行为,甚至可能只是在某些管理UI中键入SQL查询输入字段。 底线是它的非标准function。
在频谱的标准Java EE方面,有JASPIC (用户/消息认证)和JACC (授权)SPI。 两者都可用于从某些外部存储中检索与用户相关的安全相关信息。 JASPIC不能做的是在认证后改变用户的角色; 也就是说,在经过身份validation的请求 1的持续时间内,用户的角色是固定的 。 JASPIC也不能为这些角色赋予意义 ; 对于它来说,它们只是简单的String
,AS将以某种专有的方式从中获取组Principal
。 另一方面,JACC可以做这些事情,因为它建立了一个“规则库”(思考Policy
),它可以精确地关联角色,主体和Permission
并且可以在每个用户系统交互中查询。 JACC还可以覆盖或更改通过部署描述符和注释表达的Java EE安全性约束的解释。
我将在这篇文章中包含一个基于JASPIC的解决方案,并且大部分时间忽略JACC,因为:
- 您可能不需要JACC提供的额外灵活性。
- 使用自定义JACC提供程序解决方案需要相当 多 的工作,并且由于AS特定的组到角色映射而仍然不是100%标准。
- 我不知道一个开源项目使用自定义JACC提供程序来完成有意义的事情; Java EE完整配置文件 – 实现AS是唯一的例外,因为它们被强制实施规范,有时也在内部使用它们的JACC提供程序(例如,在GlassFish的情况下)。
- 围绕JASPIC仍然存在很多混乱(很多开发人员都不知道它甚至存在),这是两个规范中最简单的一个。 在继续介绍JACC之前,首先让JASPIC为更多人所知和“平易近人”是不合理的。
- 虽然现在JASPIC在线上只有很少的很好的例子,以及通过JASPIC提供商实施实际身份validation的项目,如果我错了,请纠正我 – 我还没有在SO上找到完整的JASPIC示例。
关于以下内容的一些评论:
- 如果您的应用程序/ AS /系统爆炸或被外星人等攻击,则不保证/使用风险/不起诉我
- 请尽量忽视那些优化,更好的设计或其他改进在您认为必不可少的地方。 是的,你可以承认重用DB / LDAP连接; validation插入LDAP搜索filter的用户名; 更关心线程安全; 使用TLS; 为非格式良好的XML有效负载返回400 … 解决这些问题超出了所提供解决方案的范围。 劳驾?? 你想知道unit testing在哪里???! 对不起,从来没有听说过这个词! 🙂
- 提供了具体执行组(角色)的身份validation和检索的两个SAM:“独立”,它自己完成两个任务,以及“委托”任务,顾名思义,它演示了SAM如何委派实际身份validation通过使用JASPIC LoginModule Bridge Profile工作到JAAS
LoginModule
(LM)。 后者SAM需要在AS和源级本身进行进一步的配置/调整,除非您使用的是GlassFish。 提供了附带的示例JAASlogin.conf
条目。 - 提供程序类已针对GlassFish 4.1进行了测试。 他们努力保持规范兼容,因此,如果您的产品实现了完整的Java EE(6,最好是7)配置文件,那么它应该真正适用于您的AS(显然除了第二个SAM)。 如果没有,我很抱歉; 不,我不会测试你的AS。
- 您可以避免学习/使用
AuthConfigProvider
和ServerAuthConfig
实现,但必须以专有方式(通过特定于供应商的foo-web.xml
和/或进一步使用部署/管理工具)向您的产品的AuthConfigFactory
注册实际SAM )。 您还将没有SAM实现ServerAuthContext
接口,并且必须从SAM中加载附带的Properties
。 然后,您的AS将为您实例化缺少的类,可能重用已为所有应用程序和消息层预先配置的“全局”AuthConfigProvider
和/或ServerAuthConfig
。 请注意,根据它是否在请求之间重用其实例化的ServerAuthConfig
和ServerAuthContext
(特别是后者几乎没有这种情况),SAM的生命周期可能会受到影响。 - 不包括组到角色映射,因为它是特定于容器的。
- 无论我在哪里这样做,我都会收到评论。 并非所有(完全)都无用。 在规范的帮助下,代码应该是可理解的 – 但是可以随意询问是否有什么问题困扰着你。 为超长的post道歉。
- 路径绝对来自标准Maven项目的根。 一旦在SAM中调整了属性和/或身份validation/组检索方法,就可以将所有文件构建为WAR,并在AS上按原样部署后者进行测试。 唯一的依赖是(
provided
)javaee-api
7.0(加上你的JDBC驱动程序,除非已存在于AS类路径中)。 - 由于SO的post长度限制,我不得不将代码移动到Gist 。
-
ServletContextListener
注册了AuthConfigProvider
。 保存为/
。/src/main/java/org/my/foosoft/authn/BigJaspicFactoryRegistrar.java -
AuthConfigProvider
。 保存为/
。/src/main/java/org/my/foosoft/authn/BigJaspicFactory.java -
ServerAuthConfig
。 保存为/
。/src/main/java/org/my/foosoft/authn/LittleJaspicServerFactory.java - 基本的双
ServerAuthContext
–ServerAuthModule
实现助手类。 这是实际答案的1/3。 保存为/
。/src/main/java/org/my/foosoft/authn/HttpServletSam.java - 独立的SAM实施。 实际答案,第2/3部分。 保存为
/
。/src/main/java/org/my/foosoft/authn/StandaloneLdapSam.java - JAAS LM委托SAM 。 实际答案,第3/3部分。 保存为
/
。/src/main/java/org/my/foosoft/authn/JaasDelegatingLdapSam.java - 便利例外类型 。 保存为
/
。/src/main/java/org/my/foosoft/authn/JaspicMischief.java - 随附的
Properties
。 如果您想逐字测试实际的身份validation代码,请根据您的需要调整它们。 保存为/
。/src/main/resources/org/my/foosoft/authn/jaspic-provider.properties - 附带示例
login.conf
片段(6); 请参阅供应商的文档,了解实际的文件系统位置。 -
/
(可选 – 用于演示目的: JSF支持bean )/src/main/java/org/my/foosoft/presentation/UserUtils.java -
/
(可选 – 用于演示目的: 不受保护的索引页面 )/src/main/webapp/index.xhtml -
/
(可选 – 用于演示目的: 登录页面 )/src/main/webapp/login.xhtml -
/
(可选 – 用于演示目的:角色/src/main/webapp/restricted/info.xhtml access_restricted_pages
用户的受保护索引页 ) -
/
(可选 – 用于演示目的和为了完整性: web模块DD )/src/main/webapp/WEB-INF/web.xml
进一步阅读:
- JSR-196(JASPIC)规范
- Arjan Tijms的 JASPIC ZEEF页面
- JSR-115(JACC)规范
1 JASPIC是一个非常通用的SPI,理论上可以在插入有能力的消息处理运行时时对JMS,SAML-over-SOAP和任何其他类型的消息进行身份validation。 即使其主要使用的Servlet容器配置文件也不会过度限制它。
JASPIC的低级,灵活性质意味着不了解特定于协议的function,例如HTTP会话。 因此, ServerAuthContext
s / SAM由运行时触发,以对每个请求执行身份validation。
然而,该规范通过允许SAM通过MessageInfo
Callback Property请求运行时启动容器认证会话来对此潜在缺点做出规定。 当要求对同一客户端的后续请求进行身份validation时,SAM可以通过要求运行时重用先前建立的AS身份validation会话来避免重复整个过程,从而重用用户身份(呼叫者和/或组Principal
)。 这是通过执行示例代码的HttpServletSam
中显示的“do-nothing- / leave-authentication-state-as-is-protocol”来完成的。
最后应该注意的是,JASPIC和Servlet规范都没有明确定义容器认证会话是什么。 对于SAM认证用户,出于所有实际目的,我会认为AS认证会话等同于HTTP会话,只要a)认证属于单个应用程序上下文并且b)SAM,如上所述,表示在每个请求上重用AS认证会话。
您可以使用Spring Security对其进行自定义,对LDAP进行身份validation并配置身份validation管理器/身份validation提供程序: