挂起容器请求LDAP用户角色的进程

时间:2015-10-22 11:53:57

标签: java security java-ee ldap

在我的应用程序中,我使用基于表单的身份验证和LDAP-Realm。对于授权,我使用数据库。据我所知,这工作如下

App  --> (user, pass) --> LDAP 
     <--    OK, user exists --

     --> ask for security roles for 'user' --> JACC / Database
     <--              Administrator         --

我可以挂钩我的应用程序调用{​​{1}}的过程吗?

背景:

LDAP说:ask for security roles for 'user'

数据库:Okay, 'user' is authentified

现在我想自定义数据库查询:give me all roles where username = user

这有可能吗?

2 个答案:

答案 0 :(得分:2)

TL; DR:请查看thisthat以获取示例解决方案。

您要求的内容取决于您使用的供应商特定功能提供的灵活程度;您的产品可能会或可能不会允许您扩展/ LoginModule / Realm / IdentityStore /其他人/他们重新称为专有权的行为class(es),甚至可能只是在一些管理UI的输入字段中输入SQL查询。底线是它的非标准功能。

在频谱的标准Java EE方面,有 JASPIC (用户/消息认证)和 JACC (授权)SPI。两者都可用于从某些外部存储中检索与用户相关的安全相关信息。 JASPIC无法做的是在身份验证后更改用户的角色;也就是说,在经过身份验证的请求 1 期间,用户的角色已修复。 JASPIC也不能将含义附加到这些角色;因为它们只是简单String s,AS将以某种专有方式从中派生出Principal组。另一方面,JACC可以做这些事情,因为它建立了一个&#34;规则库&#34; (想想Policy)精确地关联角色,主体和Permissions,并且可以在每个用户 - 系统交互中查询。 JACC还可以覆盖或更改通过部署描述符和注释表达的Java EE安全性约束的解释。

我将在这篇文章中包含一个基于JASPIC的解决方案,并且在很大程度上忽视JACC,因为:

  • 您可能不需要JACC提供的额外灵活性。
  • 使用自定义JACC提供商解决方案需要quite a bit of work,并且由于特定于AS的组到角色映射而仍然不是100%标准。
  • 我没有意识到使用自定义JACC提供程序来完成有意义的事情的开源项目; Java EE Full Profile-实施AS是唯一的例外,因为他们被要求实施规范,有时也在内部使用他们的JACC提供者(例如在GlassFish的情况下)。
  • 围绕JASPIC仍然存在很多混乱(很多开发人员都不知道它甚至存在),这是两个规范中最简单的一个。首先让JASPIC知道并且“平易近人”#34;在继续介绍JACC之前,请接触更多人。
  • 虽然现在JASPIC在线上只有很少的很好的例子,以及通过JASPIC提供商实施实际身份验证的项目,如果我错了,请纠正我 - 我还没有找到完整的JASPIC例如SO。

关于以下内容的一些评论:

  • 如果您的应用/ AS /系统爆炸或被外星人等攻击,则不保证/使用风险自负/不要起诉我。
  • 请尽量忽视那些优化,更好的设计或其他改进在您认为必不可少的地方。是的,你可以承认重用DB / LDAP连接;验证插入LDAP搜索过滤器的用户名;更关心线程安全;使用TLS;为非格式良好的XML有效负载返回400 ...解决这些问题超出了所提供解决方案的范围。劳驾??你想知道单元测试在哪里???对不起,从来没有听说过这个词! :)
  • 提供了两个具体执行组(角色)身份验证和检索的SAM:一个独立的&#34;,它可以自己完成两个任务,以及一个&#34;委托&#34;一,正如其名称所示,通过使用JASPIC LoginModule Bridge Profile ,演示SAM如何将实际身份验证工作委派给JAAS LoginModule(LM)。后者SAM需要在AS和源级本身进行进一步的配置/调整,除非您使用的是GlassFish。提供了附带的示例JAAS login.conf条目。
  • 提供程序类已针对GlassFish 4.1进行了测试。他们努力保持规范兼容,因此,如果您的产品实现了完整的Java EE(6,最好是7)配置文件,那么它应该真正适用于您的AS(显然除了第二个SAM)。我很抱歉,如果它没有;不,我不会在你的AS上测试。
  • 您可以避免学习/使用AuthConfigProviderServerAuthConfig实施,但必须以专有方式向您的产品AuthConfigFactory注册实际的SAM(通过特定于供应商的foo-web.xml和/或进一步使用部署/管理工具)。此外,您不会让SAM实施ServerAuthContext接口,并且必须从SAM中加载随附的Properties。然后,您的AS将为您实例化缺少的类,可能会重用&#34; global&#34; AuthConfigProvider和/或ServerAuthConfig已为所有应用程序和消息层预先配置。请注意,根据它是否在请求中重用其实例化的ServerAuthConfigServerAuthContext(特别是后者几乎没有这种情况),您的SAM的生命周期可能会受到影响。
  • 未涵盖组到角色映射,因为它是特定于容器的。
  • 无论我在哪里这样做,我都会收到评论。并非所有(完全)都无用。在规范的帮助下,代码应该是可理解的 - 但是可以随意询问是否有什么问题困扰着你。为超长的帖子道歉。
  • 路径绝对来自标准Maven项目的根。一旦您在SAM中调整了属性和/或身份验证/组检索方法,您就可以将所有文件构建为WAR,并在AS上按原样部署后者进行测试。唯一的依赖是(providedjavaee-api 7.0(加上你的JDBC驱动程序,除非已存在于AS类路径中)。
  • 由于SO的帖子长度限制,我不得不将代码移到Gist
  1. ServletContextListener注册AuthConfigProvider。保存为/<project>/src/main/java/org/my/foosoft/authn/BigJaspicFactoryRegistrar.java
  2. AuthConfigProvider。保存为/<project>/src/main/java/org/my/foosoft/authn/BigJaspicFactory.java
  3. ServerAuthConfig。保存为/<project>/src/main/java/org/my/foosoft/authn/LittleJaspicServerFactory.java
  4. 基本双ServerAuthContext - ServerAuthModule实现帮助程序类。这是实际答案的1/3。保存为/<project>/src/main/java/org/my/foosoft/authn/HttpServletSam.java
  5. standalone SAM实施。实际答案,第2/3部分。保存为/<project>/src/main/java/org/my/foosoft/authn/StandaloneLdapSam.java
  6. JAAS LM-delegating SAM。实际答案,第3/3部分。保存为/<project>/src/main/java/org/my/foosoft/authn/JaasDelegatingLdapSam.java
  7. 便利exception type。保存为/<project>/src/main/java/org/my/foosoft/authn/JaspicMischief.java
  8. 随附的Properties。如果您想逐字测试实际的身份验证代码,请根据您的需要调整它们。保存为/<project>/src/main/resources/org/my/foosoft/authn/jaspic-provider.properties
  9. 随附sample login.conf代码段(6);有关实际文件系统位置,请参阅供应商的文档。
  10. /<project>/src/main/java/org/my/foosoft/presentation/UserUtils.java(可选 - 用于演示目的:JSF backing bean
  11. /<project>/src/main/webapp/index.xhtml(可选 - 用于演示目的:unprotected index page
  12. /<project>/src/main/webapp/login.xhtml(可选 - 用于演示目的:login page
  13. /<project>/src/main/webapp/restricted/info.xhtml(可选 - 用于演示目的:protected index page适用于角色access_restricted_pages中的用户)
  14. /<project>/src/main/webapp/WEB-INF/web.xml(可选 - 用于演示目的和为了完整性:web module DD
  15. 进一步阅读:

    1. JSR-196 (JASPIC) Specification
    2. Arjan Tijms's JASPIC ZEEF page
    3. JSR-115 (JACC) Specification
    4. 1 JASPIC是一个非常通用的SPI,理论上可以在插入功能强大的消息处理运行时时对JMS,SAML-over-SOAP和任何其他类型的消息进行身份验证。即使其主要使用的 Servlet容器配置文件也不会过度限制它。

      JASPIC的低级,灵活性质意味着不了解特定于协议的功能,例如HTTP会话。因此,运行时会触发ServerAuthContext s / SAM以对每个请求执行身份验证。

      该规范通过允许SAM通过MessageInfo 回调属性来请求运行时启动容器认证会话,从而对此潜在缺陷做出规定>。当被要求验证同一客户端的后续请求时,SAM可以通过要求运行时重用先前建立的AS身份验证会话来避免重复整个过程,因此用户身份(呼叫者和/或组Principal(s) )。这是通过执行&#34; do-nothing- / leave-authentication-state-as-is-protocol&#34;来完成的。显示在示例代码的HttpServletSam中。

      最后应该注意的是,JASPIC和Servlet规范都没有明确定义容器认证会话是什么。对于SAM认证用户,出于所有实际目的,我会认为AS认证会话等同于HTTP会话,只要a)认证属于单个应用程序上下文并且b)SAM,如上所述,表示在每个请求上重用AS认证会话。

答案 1 :(得分:0)

您可以使用Spring Security对其进行自定义,针对LDAP进行身份验证并配置身份验证管理器/身份验证提供程序:

<security:authentication-manager>
    <security:authentication-provider user-service-ref="userDetailsService">
        <security:jdbc-user-service data-source-ref="dataSource"                    
            authorities-by-username-query="select AUTHORITIES.AUTHORITIES_AUTH from AUTHORITIES, USERS where AUTHORITIES.AUTHORITIES_USER_ID = USERS.USERS_ID and ..."/>