在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色

Posted

技术标签:

【中文标题】在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色【英文标题】:Accessing nested LDAP roles in Oracle Internet Directory (OID) within Grails and SpringSecurity 【发布时间】:2012-11-21 12:53:30 【问题描述】:

在我们的 LDAP 目录中,我们有映射到组的用户。这些组可以映射到其他组。例如:

cn=group1,cn=groups,dc=example,dc=com
    uniquemember cn=user1,cn=user,dc=example,dc=com
cn=group2,cn=groups,dc=example,dc=com
    uniquemember cn=user2,cn=user,dc=example,dc=com
    uniquemember cn=group1,cn=user,dc=example,dc=com

所以User1属于Group1,而User2属于Group2,Group2又属于Group1

在 Grails 中,User1 对 Group1 具有权限,但 User2 仅对 Group2 具有权限。据我所见,没有办法让它递归地查看树。实际上,我可能只需要一个 2 级层次结构,但即使这样似乎也行不通。

我正在尝试通过自定义 UserDetailsContextManager 来查看是否可以遍历初始结果并按组重新查询 LDAP,但我想我会看看是否有更简单/更好的方法。

【问题讨论】:

这个问题有一个误导性的描述/示例。它声明“所以 User1 属于 Group1,但 User2 属于 Group2,Group2 又属于 Group1”,这表明 user2 应该属于 group1。这是错误的方法 - group1group2 的成员(通过 uniquemember 属性,所以正确的包含是 group2 包括 user2group1 和因此 user1。以下段落也需要更正。uniquemember 属性显示哪些对象是该组的成员,而不是该对象是哪些对象的成员。 【参考方案1】:

您可能已经看到了,但这是来自文档:

// 如果你不想支持组成员递归(组中的组),那么使用下面的设置 // grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = 'member=0' // Active Directory 特定

// 如果您希望支持以组为成员的组(递归组),请使用以下 grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = '(member:1.2.840.113556.1.4.1941:=0)' // Active Directory 特定

http://grails-plugins.github.com/grails-spring-security-ldap/docs/manual/guide/2.%20Usage.html

【讨论】:

是的,我确实看到了,但正如您可能从评论中注意到的那样,它是特定于 Active Directory 的。我正在使用 Oracle Internet Directory——我确实尝试过针对它的 AD 查询,但它不起作用。不过谢谢!【参考方案2】:

Oracle OID 有一个product-specific extension 用于遍历层次结构,称为CONNECT_BY,它的LDAP OID 为2.16.840.1.113894.1.8.3。您可以将此添加为请求控件,以要求服务器根据您指定的属性连接/遵循层次结构。这可以使用 Java LDAP 客户端程序或 OpenLDAP ldapsearch 之类的程序来完成,尽管设置有点棘手。

如果您想使用 Java 来遵循层次结构,this page 包含一个 sample program,它显示了如何设置所需的 javax.naming.ldap.Control 实现类,在本例中名为 ConnectByControl

您也可以使用ldapsearch 执行这种分层搜索,但它需要一些准备和对所需控制值的隐含理解,因为值是连接然后base64 编码的。该值分为两部分 - 跟随我的深度(0=无限),后跟连接属性名称(在这种情况下,uniquemember 是所需的名称)。将查询中的 baseDN 设置为要开始分层搜索的条目。

ldapsearch -H ldap://myoidserver.mycompany.com:389 -e 2.16.840.1.113894.1.8.3=MBECAQAEDHVuaXF1ZW1lbWJlcg== -b cn=some_group_containing_groups_nested_by_uniquemember,cn=some_groups,dc=mycompany,dc=com "(objectClass=*)" dn uniquemember

-e 2.16.840.1.113894.1.8.3= 增加了CONNECT_BY 请求控制。值 MBECAQAEDHVuaXF1ZW1lbWJlcg== 是 ASN.1 BER 编码,然后是 base64 编码值 0uniquemember,用于上述深度和属性名称。这将首先打印cn=some_group_containing_groups_nested_by_uniquemember,...dn 及其直接(用户)uniquemembers,然后每个uniquemember 将被“连接”或跟随。如果该条目本身具有一组uniquemember,即它是一个嵌套组,则该过程将继续,直到到达没有嵌套uniquemembers 的叶/用户条目。

【讨论】:

以上是关于在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色的主要内容,如果未能解决你的问题,请参考以下文章

Grails/SpringSecurity:如何在不被识别的情况下创建用户?

带有 SpringSecurity、本地用户和 LDAP 的 Grails

Grails、Vaadin 7 和 SpringSecurity:授权不起作用

在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色

将 REST 身份验证添加到 Grails + SpringSecurity 浏览器应用程序

Grails,SpringSecurity - 如果未记录,则禁用重定向