将Java EE应用程序迁移到LDAP

时间:2016-04-18 06:31:24

标签: java-ee active-directory ldap

我对LDAP(ActiveDirectory)和现有Java EE应用程序有一些疑问。

在我们的Java EE应用程序中,我们在权限处理方面进行了混合。因此,有时我们会问<img src="data:image/jpeg;base64,<?php echo base64_encode($image->picture); ?>" alt="Responsive image"> ,有时我们会问isUserInRole("rolename")

现在,我们想将这个现有的应用程序绑定到LDAP,我不知道LDAP是如何工作的;-) 所以我有几个问题:

  1. LDAP只能与群组一起使用,还是只能使用权限?
  2. 我在哪里存储权限?在LDAP或我的应用程序数据库中
  3. 我在哪里进行组和权限之间的映射? (ldap或申请)
  4. 在我的Java EE应用程序中使用LDAP时是否需要使用JAAS?
  5. 我希望你能帮我解决这些希望简单的问题!

1 个答案:

答案 0 :(得分:2)

注意:下面使用术语 LDAP 时, LDAP兼容的目录服务就是实际被引用的内容。

1. JEE应用程序应该如何限制用户在LDAP的帮助下做某些事情?

对于授权,(主要)基于角色(不要与 RBAC 混淆),Java EE安全模型仍然存在;在一天结束时,运行时仍然会根据应用程序级角色授权用户(调用者),无论 where (LDAP,关系数据库,SAML) IdP,XML文件,等等)和如何(即,哪些SQL类型,LDAP属性类型等)是持久的。实际上,某些应用程序可能无法在外部存储其呼叫者。角色成员资格,但根据相应调用者的其他属性,在身份验证期间计算它们;作为一个人为的例子,认证机制可以&#34;参见&#34;调用者uid=jdoe, dc=users, dc=some, dc=org的{​​{1}}属性指的是过去3年以上的日期,以及开发者hireDate属性,从而推断{ {1}}是高级开发人员,将其指定为实际角色。

2.我在哪里存储权限?在LDAP或我的应用程序数据库中?
3.组和权限之间的映射在哪里? (ldap或申请)

首先,您对权限的概念不适合Java EE安全模型,因此我的建议是完全删除权限并直接使用相应的角色。这样做的好处应该是显而易见的:您可以从编程式授权转变为纯粹的声明式授权,因为现在可以启用运行时来为您处理所有授权检查。请注意,您绝不会将角色视为用户组的等同物;虽然他们确实可以表达粗糙的东西,如编辑&#34;和&#34; can-view-stats-panel&#34;,他们也可以表达一些细粒度的&#34; can-access-method-void-getBonus(BigDecimal)-of-instance-123-of -ejb-BonusGranter-与精氨酸 - 不大于-100 $ -during,工作小时,每-的13中,每一月之间,08:00:10Z-和08:01:09Z-如果-勤奋和天气&#39; S-晴天和经理&#39; S-IN-A-好心情&#34; (你显然必须提出一个很好的约定,能够以紧凑和直观的方式表达所有这些,但你明白了。)

还有一个名为 JACC 的规范,您的Java EE产品可能支持也可能不支持。如果绝对需要比角色提供的更多灵活性,理论上你可以利用它,因为它基本上允许你使用Java SE jobTitle来确定 - on jdoe的基础 - 分配低级,看似无限灵活的Policy - 呼叫者是否确实有角色。无论如何,目标保持不变:将与授权相关的代码与业务逻辑分离。

至于你实际的两个问题 - 这不应该只适用于你的权限(如果你想保留它们),但是对于大多数持久性数据 - 我的简单回答是如果有问题的数据其他应用程序需要(或在可预见的将来它依赖的可能性很高),并且可以&#34;适合&#34;在目录信息树(不一定是这种情况)中,它可以存储在LDAP中。否则,它应该存储&#34;更近&#34;对于应用程序,例如在应用程序&#34;专用&#34;数据库,正如你的建议。还要记住,至少在传统上,LDAP被认为是存储具有低读写比的数据的存储库的不良选择。我不知道在多大程度上 - 如果有的话 - 性能考虑目前仍然有效,但我仍然不会使用LDAP来保存高度动态的数据,比如Web服务的响应时间或可用性百分比。 / p>

4.在我的Java EE应用程序中使用LDAP时是否需要使用JAAS?

必须(直接)依赖JAAS进行Java EE中的身份验证或授权。该主题已在其他地方进行了广泛讨论,因此我在此不再详述。为了利用容器管理的授权,如前所述,您仍然必须使用容器管理的身份验证,其主要目的是建立身份(调用者 >(角色)Principal s)您的呼叫者与运行时。现在,理想情况下,您只需声明以下内容

java.security.Permission

在您的Principal中,身份验证将 工作。遗憾的是,Java EE不是这种情况(至少从版本7开始,因为该领域的一些有希望的变化预计将包含在平台的下一个版本中)。假设您仍想使用容器管理的身份验证,则有两个选项:

a)使用JASPIC编写一个可移植的身份验证机制。您的<login-config> <auth-method>FORM</auth-method> <LDAP-identity-store> <base-DN>dc=users, dc=some, dc=org</base-DN> <bind-DN>uid=admin</bind-DN> <bind-credential> <credential-alias ref="admin_LDAP_pass"/> </bind-credential> <base-search-DN>dc=users, dc=some, dc=org</base-search-DN> <search-filter>(uid={username_HTTP_param})</search-filter> </LDAP-identity-store> </login-config> 基本上会:

  1. 针对LDAP连接并验证您的呼叫者(即其表单 - web.xml ed用户名),如果成功,
  2. 检索(和/或计算)来电者的角色(此时称为群组),
  3. 实例化经过身份验证的调用方的javax.security.auth.message.module.ServerAuthModule表示
  4. 实例化POST名称(运行时将从中构建相应的 Principal),最后
  5. 通过特定于JASPIC的String[]将前两个步骤的结果传达给运行时。
  6. 优点:在所有完整Java EE Profile实现以及Jetty和Tomcat(从9.0.0.M4开始)上受支持。
    缺点:需要一些努力,并不总是得到最佳支持。

    b)创建特定于供应商的身份验证扩展,基于JAAS或以其他方式,基本上完成相同的步骤,尽管通过专有API。

    优点:通常需要编写零代码(当然更少的样板) 缺点:非便携式方法。

    <小时/> 进一步阅读: