请根据提示描述你遇到的问题

例如 memberOf出现俩次,但是search方法拿到遍历出只有一个memberOf,丢失一个

基于Monster 组和GPT的调写:

  • 要验证用户的账号和密码是否正确,可以使用LDAP提供的bind()方法,将用户提供的用户名和密码作为参数绑定到LDAP目录树上的用户对象上。如果绑定成功,则表示提供的用户名和密码是正确的。

下面是一个简单的示例代码:

public static boolean authenticate(LdapContext ctx, String username, String password) {
    boolean result = false;
    try {
        ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, "uid=" + username);
        ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
        ctx.reconnect(null);
        result = true;
    } catch (NamingException e) {
        e.printStackTrace();
    }
    return result;
}


在这个示例中,我们使用用户提供的用户名和密码来绑定LDAP目录树上的用户对象。如果绑定成功,则返回true,否则返回false。

关于搜索用户属性出现重复的问题,可能是由于LDAP目录树中的用户对象有多个属性具有相同的名称。为了避免这种情况,可以使用Attribute.getAll()方法获取属性的所有值,而不是只使用Attribute.get()方法获取第一个值。这样可以保证获取到所有的属性值,避免丢失任何一个属性值。

下面是修改后的示例代码:


public static List<LdapUser> search(LdapContext ctx,String basedn){
    List<LdapUser> lm=new ArrayList<LdapUser>();
    try {
        if(ctx!=null){
            //过滤条件
            String filter = "(objectClass=*)";
            String[] attrPersonArray = { "objectClass","uid", "userPassword", "displayName", "cn", "sn", "mail", "description","objectGUID","member" };
            SearchControls searchControls = new SearchControls();//搜索控件
            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);//搜索范围,设为2会查询子节点。
            searchControls.setDerefLinkFlag(false);
            searchControls.setReturningAttributes(attrPersonArray);
            NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter,searchControls);
            int num= 0;
            while (answer.hasMore()) {
                SearchResult result = (SearchResult) answer.next();
                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
                LdapUser lu=new LdapUser();
                while (attrs.hasMore()) {
                    Attribute attr = (Attribute) attrs.next();
                    num++;
                    if("uid".equals(attr.getID())){
                        lu.setUid(attr.get().toString());
                    }else if("displayName".equals(attr.getID())){
                        lu.setDisplayName(attr.get().toString());
                    }else if("cn".equals(attr.getID())){
                        lu.setCn(attr.get().toString());
                    }else if("sn".equals(attr.getID())){
                        lu.setSn(attr.get().toString());
                    }else if("memberOf".equals(attr.getID())) {
                        // 处理属性值出现重复的情况
                        NamingEnumeration<?> values = attr.getAll();
                        while (values.hasMore()) {
                            String value = values.next().toString();
                            if (value.startsWith("cn=")) {
                                lu.addMemberOf(value);
                            }
                        }
                    }
                }
 
                if(lu.getUid()!=null)
                    lm.add(lu);
 
            }
        }
    }catch (Exception e) {
        e.printStackTrace();
    }
    return lm;
}

在处理"memberOf"属性时,使用Attribute.getAll()方法获取属性的所有值,然后使用一个循环遍历每个属性值,将以"cn="开头的属性值添加到LdapUser对象的memberOf属性中。这样就可以避免丢失任何一个属性值了。

引用chatGPT作答,要校验用户的账号和密码是否正确,可以使用Bind操作。Bind操作会将用户名和密码发送到LDAP服务器进行验证,如果成功则说明用户名和密码正确。可以通过以下代码实现Bind操作:

public static boolean bind(LdapContext ctx, String username, String password, String userDn) {
    boolean result = false;
    try {
        ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
        ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
        ctx.reconnect(null);
        result = true;
    } catch (NamingException e) {
        e.printStackTrace();
    }
    return result;
}

其中,ctx是已经连接到LDAP服务器的LdapContext对象,username是用户登录时输入的用户名,password是用户登录时输入的密码,userDn是LDAP中该用户的DN。

要解决重复属性的问题,可以通过修改返回的属性数组来处理。在这里,可以创建一个Set对象,每次遍历属性时将其添加到Set中,这样就可以去除重复属性。修改的代码如下:

public static List<LdapUser> search(LdapContext ctx,String basedn){
    List<LdapUser> lm=new ArrayList<LdapUser>();
    try {
        if(ctx!=null){
            //过滤条件
            String filter = "(objectClass=*)";
            String[] attrPersonArray = { "objectClass","uid", "userPassword", "displayName", "cn", "sn", "mail", "description","objectGUID","member" };
            SearchControls searchControls = new SearchControls();//搜索控件
            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);//搜索范围,设为2会查询子节点。
            searchControls.setDerefLinkFlag(false);
            searchControls.setReturningAttributes(attrPersonArray);
            NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter,searchControls);
            int num= 0;
            while (answer.hasMore()) {
                SearchResult result = (SearchResult) answer.next();
                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
                LdapUser lu=new LdapUser();
                Set<String> memberOfs = new HashSet<>(); // 创建一个Set对象
                while (attrs.hasMore()) {
                    Attribute attr = (Attribute) attrs.next();
                    num++;
                    if("uid".equals(attr.getID())){
                        lu.setUid(attr.get().toString());
                    }else if("displayName".equals(attr.getID())){
                        lu.setDisplayName(attr.get().toString());
                    }else if("cn".equals(attr.getID())){
                        lu.setCn(attr.get().toString());
                    }else if("sn".equals(attr.getID())){
                        lu.setSn(attr.get().toString());
                    }else if("memberOf".equals(attr.getID())){
                        memberOfs.add(attr.get().toString()); // 将属性添加到Set对象中
                    }
                }

                if(lu.getUid()!=null)
                    lm.add(lu);
                if(!memberOfs.isEmpty()){ // 如果Set对象不为空,则将其转换为数组并设置到LdapUser对象中
                    String[] memberOfArray = memberOfs.toArray(new String[0]);
                    lu.setMemberOf(memberOfArray);
                }
            }
        }
    }catch (Exception e) {
        e.printStackTrace();
    }
    return lm;
}

用户登录验证小案例

可以借鉴下
https://blog.csdn.net/iLuosa/article/details/116156600