Spring Boot / Spring LDAP获取用户成员列表 [英] Spring Boot / Spring LDAP Get List of memberof for a User

查看:1000
本文介绍了Spring Boot / Spring LDAP获取用户成员列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望通过从以下结构化的LDAP存储库查询其ID来获取用户属性列表

I want to get a list of a users attributes by querying on their ID from an LDAP repository structured like below

dn: uid=E000001 ,ou=People,o=Company,o=Internal
cn: BOB DOLE
statusid: active
memberof: cn=foo_group, cn=Foos, ou=Groups, o=Company,o=Internal
memberof: cn=bar_group, cn=Foos, ou=Groups, o=Company,o=Internal

dn: uid=E000002 ,ou=People,o=Company,o=Internal
cn: MARK TEST
statusid: active
memberof: cn=foo_group, cn=Foos, ou=Groups, o=Company,o=Internal
memberof: cn=bar_group, cn=Foos, ou=Groups, o=Company,o=Internal

例如,我查询用户IDE00001。我想退回此

So for example I query on the user id "E00001". I want to return this

["cn=foo_group, cn=Foos, ou=Groups, o=Company,o=Internal", "cn=bar_group, cn=Foos, ou=Groups, o=Company,o=Internal"


推荐答案

以下是检索用户组的多种方法:

Here's multiple ways to retrieve user groups:


  • 如果你有一个没有嵌套组的简单LDAP服务器,memberOf通常就够了:

  • In case that you have a simple LDAP server with no nested groups, memberOf is usually enough:

String userCN = "user1";

//Get the attribute of user's "memberOf"
ArrayList<?> membersOf = ldapTemplate.search(
        query().where("sAMAccountName").is(userCN),
        (AttributesMapper<ArrayList<?>>) attrs -> Collections.list(attrs.get("memberOf").getAll())
).get(0);


  • 但是如果你有嵌套组,事情会变得更复杂:

  • But in case you have nested groups, things become more complicated:

    /*
     * Get user distinguised name, example: "user" -> "CN=User Name,OU=Groups,OU=Domain Users,DC=company,DC=something,DC=org"
     * This will be used for our query later
     */
    String distinguishedName = ldapTemplate.search(
            query().where("sAMAccountName").is(userCN),
            (AttributesMapper<String>) attrs -> attrs.get("distinguishedName").get().toString()
    ).get(0); //.get(0): we assume that search will return a result 
    
    /*
     * This one recursively search for all (nested) group that this user belongs to
     * "member:1.2.840.113556.1.4.1941:" is a magic attribute, Reference: 
     * https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx
     * However, this filter is usually slow in case your ad directory is large.
     */
    List<String> allGroups = ldapTemplate.search(
            query().searchScope(SearchScope.SUBTREE)
                    .where("member:1.2.840.113556.1.4.1941:").is(distinguishedName),
            (AttributesMapper<String>) attrs -> attrs.get("cn").get().toString()
    );
    


  • 对于googlers:请注意,这依赖于 org.springframework.boot:spring-boot-starter-data-ldap ,以防有人需要Bean初始化代码:

    For googlers: note that this has dependency of org.springframework.boot:spring-boot-starter-data-ldap, and in case someone needs the Bean initialization code:

    @Component
    @EnableConfigurationProperties
    public class Ldap {
        @Bean
        @ConfigurationProperties(prefix="ldap.contextSource")
        public LdapContextSource contextSource() {
            return new LdapContextSource();
        }
    
        @Bean
        public LdapTemplate ldapTemplate(ContextSource contextSource) {
            return new LdapTemplate(contextSource);
        }
    }
    

    在application.yml中使用以下配置模板:

    with the following config template in application.yml:

    ldap:
        contextSource:
            url: ldap://your-ldap.server
            base: dc=Company,dc=Domain,dc=Controller
            userDn: username
            password: hunter2
            #you'll want connection polling set to true so ldapTemplate reuse the connection when searching recursively
            pooled: true
    






    For当幻数的表现不好时:如果你的ldap目录很大,那么使用幻数的最后一个实际上很慢,并且在这种情况下递归搜索ldap更快。这是一个帮助类,可以详尽地搜索用户所属的所有组:


    For when magic number's performance is bad: The last one using magic number is actually quite slow if your ldap directory is large, and searching ldap recursively is faster in this case. Here's a helper class to exhaustively search all groups that a user belongs to:

    public class LdapSearchRecursive {
        private final LdapTemplate ldapTemplate;
        private Set<String> groups;
    
        public LdapSearchRecursive(LdapTemplate ldapTemplate) {
            this.ldapTemplate = ldapTemplate;
            this.groups = new HashSet<>();
        }
    
        /**
         * Retrieve all groups that this user belongs to.
         */
        public Set<String> getAllGroupsForUserRecursively(String userCN) {
            List<String> distinguishedNames = this.ldapTemplate.search(
                    query().where("objectCategory").is("user").and(
                            query().where("sAMAccountName").is(userCN)
                                    .or(query().where("userPrincipalName").is(userCN))
                    ),
                    (AttributesMapper<String>) attrs -> attrs.get("distinguishedName").get().toString()
            );
    
            if (distinguishedNames.isEmpty()) {
                throw new UsernameNotFoundException("User not recognized in LDAP");
            }
    
            return this.getAllGroupsRecursivelyByUserDistinguishedName(distinguishedNames.get(0), null);
        }
    
        private Set<String> getAllGroupsRecursivelyByUserDistinguishedName(String dn, @Nullable String parentDN) {
            List<String> results = this.ldapTemplate.search(
                    query().where("member").is(dn),
                    (AttributesMapper<String>) attrs -> attrs.get("distinguishedName").get().toString()
            );
    
            for (String result : results) {
                if (!(result.equals(parentDN) //circular, ignore
                        || this.groups.contains(result) //duplicate, ignore
                        )) {
                    this.getAllGroupsRecursivelyByUserDistinguishedName(result, dn);
                }
            }
            this.groups.addAll(results);
    
            return this.groups;
        }
    }
    

    这篇关于Spring Boot / Spring LDAP获取用户成员列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆