java对Ldap操作3

package ldap.imp;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import ldap.UserDaoLdap;
import ldap.pojo.LdapPersonInfo;

import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;

/**
 * 
@author zhangliang UserDaoLdap接口的实现类,主要实现ldap用户认证、查询接口
 
*/

public class UserDaoLdapImpl implements UserDaoLdap {
    
/**
     * 定义使用springframework对ldap的访问操作对象 借助LdapTemplate可以实现大部分对ldap的操作
     
*/

    
private LdapTemplate ldapTemplate;

    
/**
     * 
@param ldapTemplate
     *            spring setter 注入
     
*/

    
public void setLdapTemplate(LdapTemplate ldapTemplate) {
        
this.ldapTemplate = ldapTemplate;
    }


    
/**
     * 获得所有的用户名(ldap称cn),可根据第二个参数指定返回值是否重复
     * 
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@param distinct
     *            true,去掉结构中的重复值;false 允许结果中包含重复值
     * 
@return 查询范围下返回的cn列表
     
*/

    
public List<String> getAllPersonNames(int scope, boolean distinct) {
        
// 存储查询结果的集合
        final ArrayList<String> allPersonCnList = new ArrayList<String>();
        
// 使用ldapTemplate提供的接口查询,objectclass=person 表示对象为person的对象
        ldapTemplate.search("""(objectclass=person)",
                createSearchControls(scope), 
new AttributesMapper() {
                    
public Object mapFromAttributes(Attributes attrs)
                            
throws NamingException {
                        
// 获取cn的属性,用户名存在cn中
                        Attribute attr = attrs.get("cn");
                        
// 若没有该属性返回null
                        if (attr == null{
                            
return null;
                        }
 else // 获取属性
                            
// 若包含多个cn属性,需要循环获取
                            Enumeration ent = attr.getAll();
                            
while (ent.hasMoreElements()) {
                                allPersonCnList.add(ent.nextElement()
                                        .toString());
                            }

                        }

                        
return null;
                    }

                }
);
        
// true,去掉结果中的重复值
        if (distinct) {
            ArrayList
<String> templist = new ArrayList<String>();
            
for (String cn : allPersonCnList)
                
if (!templist.contains(cn)) {
                    templist.add(cn);
                }

            
// 返回无重复值的结果
            return templist;
        }

        
// 返回包含重复值的结果
        return allPersonCnList;
    }


    
/**
     * 查询指定范围下的所有用户信息
     * 
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@return 查询范围下返回的所有用户信息列表
     
*/

    
public List getAllPersons(int scope) {
        
// 使用ldapTemplate提供的接口查询,objectclass=person 表示对象为person的对象
        return ldapTemplate.search("""(objectclass=person)",
                createSearchControls(scope), 
new LdapObjectAttributesMapper());
    }


    
/**
     * 根据Uid查询用户信息,*代表任意长度的任意字符
     * 
     * 
@param uid
     *            用户的uid
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@return 用户信息
     
*/

    
public List getPersonByUid(String uid, int scope) {
        
// 使用ldapTemplate提供的接口查询,objectclass=person 表示对象为person的对象
        
// uid 和 objectclass 组成联合查询条件,两个同时满足的查询结果
        return ldapTemplate.search("""(&(objectclass=person)(uid=" + uid
                
+ "))", createSearchControls(scope),
                
new LdapObjectAttributesMapper());
    }


    
/**
     * 查询包含当前Cn信息的所有用户,*代表任意长度的任意字符
     * 
     * 
@param cn
     *            用户的cn
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@return 用户列表
     
*/

    
public List getPersonByCn(String cn, int scope) {
        
// 使用ldapTemplate提供的接口查询,objectclass=person 表示对象为person的对象
        
// cn 和 objectclass 组成联合查询条件,两个同时满足的查询结果
        return ldapTemplate.search("",
                
"(&(objectclass=person)(cn=" + cn + "))",
                createSearchControls(scope), 
new LdapObjectAttributesMapper());
    }


    
/**
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@return 返回查询控制器对象
     
*/

    
private SearchControls createSearchControls(int scope) {
        
// 查询控制类SearchControls设定查询范围
        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(scope);
        
return constraints;
    }


    
/**
     * 使用LdapPersonInfo类对象实现复合查询,属性中可使用通配符*,*代表任意长度的任意字符
     * 
     * 
@param ldapPersonInfo
     *            查询条件
     * 
@param scope
     *            取值为0、1、2,分别对应 SearchControls 类 OBJECT_SCOPE, ONELEVEL_SCOPE,
     *            SUBTREE_SCOPE三个查询范围,分别代表 当前对象查询、当前节点下对象查询、当前节点所有子目录查询
     * 
     * 
@return 用户列表
     
*/

    
public List getPersonByPersonEnty(LdapPersonInfo ldapPersonInfo, int scope) {
        
// strb存储、组装查询条件集合
        StringBuffer strb = new StringBuffer("(&(objectclass=person)");
        
// uid 属性
        if (ldapPersonInfo.getUid() != null && ldapPersonInfo.getUid() != ""{
            strb.append(
"(uid=" + ldapPersonInfo.getUid() + ")");
        }

        
// givenname 属性
        if (ldapPersonInfo.getFirstName() != null
                
&& ldapPersonInfo.getFirstName() != ""{
            strb.append(
"(givenname=" + ldapPersonInfo.getFirstName() + ")");
        }

        
// sn 属性
        if (ldapPersonInfo.getLastName() != null
                
&& ldapPersonInfo.getLastName() != ""{
            strb.append(
"(sn=" + ldapPersonInfo.getLastName() + ")");
        }

        
// cn 属性
        if (ldapPersonInfo.getCn() != null && ldapPersonInfo.getCn().size() > 0{
            
for (int i = 0; i < ldapPersonInfo.getCn().size(); i++)
                strb.append(
"(cn=" + ldapPersonInfo.getCn().get(i) + ")");
        }

        
// telephonenumber 属性
        if (ldapPersonInfo.getTelephone() != null
                
&& ldapPersonInfo.getTelephone() != ""{
            strb.append(
"(telephonenumber=" + ldapPersonInfo.getTelephone()
                    
+ ")");
        }

        
// facsimiletelephonenumber 属性
        if (ldapPersonInfo.getFax() != null && ldapPersonInfo.getFax() != ""{
            strb.append(
"(facsimiletelephonenumber=" + ldapPersonInfo.getFax()
                    
+ ")");
        }

        
// mail 属性
        if (ldapPersonInfo.getMail() != null && ldapPersonInfo.getMail() != ""{
            strb.append(
"(mail=" + ldapPersonInfo.getMail() + ")");
        }

        String filter 
= strb.append(")").toString();
        
return ldapTemplate.search("", filter, createSearchControls(scope),
                
new LdapObjectAttributesMapper());
    }


    
/**
     * 根据dn查找用户,dn为base dn 的相对dn.(若basedn为:dc=koal,dc=com,user
     * dn为:uid=123,dc=koal,dc=com,则此处只需要提供 123 作为参数)
     * 
     * 
@param dn
     *            相对base dn的dn参数
     * 
@return 用户信息
     
*/

    
public LdapPersonInfo getLdapObjectByDn(String dn) {
        
return (LdapPersonInfo) ldapTemplate.lookup(dn,
                
new LdapObjectAttributesMapper());
    }


    
/**
     * 登陆验证
     * 
     * 
@param userDn
     *            用户的user dn
     * 
@param password
     *            用户登陆密码
     * 
@return 登陆成功返回true,不成功返回false
     
*/

    
private boolean loginCheack(String userDn, String password) {
        
// 获取DirContext对象
        DirContext ctxs = ldapTemplate.getContextSource().getReadOnlyContext();
        
try {
            
// 组装登陆ldap需要的信息数据
            Hashtable<Object, Object> ht = new Hashtable<Object, Object>();
            
// 获取已有的登陆信息
            ht = (Hashtable<Object, Object>) ctxs.getEnvironment();
            
// 设置用户
            ht.put(Context.SECURITY_PRINCIPAL, userDn);
            
// 设置用户登陆密码
            ht.put(Context.SECURITY_CREDENTIALS, password);
            
// 设置用户验证方式为simple
            ht.put(Context.SECURITY_AUTHENTICATION, "simple");
            
// 出现异常时表示用当前登陆人登陆失败
            DirContext c = new InitialDirContext(ht);
            c.close();
            
return true;
        }
 catch (Exception e) {
            
// e.printStackTrace();
            System.out.println("login false");
            
return false;
        }
 finally {
            
try {
                ctxs.close();
            }
 catch (Exception ie) {

            }

        }

    }


    
/**
     * 验证用户登陆
     * 
     * 
@param uid
     *            用户uid
     * 
@param password
     *            用户密码
     * 
     * 
@return 是否登陆成功
     
*/

    
public boolean userLogin(String uid, String password) {
        
// 获取用户id所在ldap中的user dn
        List dnlist = getUserDnByUid(uid);
        
// 根据查询到的所有dn遍历,检查是否某一user dn与用户密码可以登陆ldap
        for (Object dn : dnlist) {
            
if (loginCheack(dn.toString(), password) == true{
                
return true;
            }

        }

        
return false;
    }


    
/**
     * 查询用户user dn
     * 
     * 
@param uid
     *            用户uid
     * 
     * 
@return 用户dn列表,当前目录节点下可能存在多个相同uid的多个user dn
     
*/

    
public List<String> getUserDnByUid(String uid) {
        
// 获取DirContext对象
        DirContext ctx = ldapTemplate.getContextSource().getReadOnlyContext();
        
// 存储用户dn
        ArrayList<String> dn = new ArrayList<String>();
        
try {
            SearchControls constraints 
= new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration en 
= ctx.search("""uid=" + uid, constraints);
            
// 查询所有用户
            while (en != null && en.hasMoreElements()) {
                Object obj 
= en.nextElement();
                
if (obj instanceof SearchResult) {
                    SearchResult si 
= (SearchResult) obj;
                    
// 获取dn并添加到查询列表
                    dn.add(si.getNameInNamespace());
                }

            }

            ctx.close();
        }
 catch (Exception e) {
            e.printStackTrace();
            
try {
                ctx.close();
            }
 catch (Exception ee) {
                ee.printStackTrace();
            }

        }

        
return dn;
    }


    
/**
     * ldap用户信息数据填充类 将获取的属性信息封装为LdapObject对象
     * 
     
*/

    
private class LdapObjectAttributesMapper implements AttributesMapper {
        
public Object mapFromAttributes(Attributes attrs)
                
throws NamingException {
            LdapPersonInfo LdapObject 
= new LdapPersonInfo();
            
try {
                
// 获取并封装uid属性
                LdapObject.setUid((String) getAttribute(attrs, "uid"));
                
// 获取并封装givenname属性
                LdapObject.setFirstName((String) getAttribute(attrs,
                        
"givenname"));
                
// 获取并封装sn属性
                LdapObject.setLastName((String) getAttribute(attrs, "sn"));
                
// 获取并封装cn属性
                LdapObject.setCn(getMoreSameAttributes(attrs, "cn"));
                
// 获取并封装telephonenumber属性
                LdapObject.setTelephone((String) getAttribute(attrs,
                        
"telephonenumber"));
                
// 获取并封装facsimiletelephonenumber属性
                LdapObject.setFax((String) getAttribute(attrs,
                        
"facsimiletelephonenumber"));
                
// 获取并封装mail属性
                LdapObject.setMail((String) getAttribute(attrs, "mail"));
            }
 catch (NamingException n) {
                n.printStackTrace();
            }

            
// 返回封装后的用户对象
            return LdapObject;
        }


        
/**
         * 从属性列表中获取指定的属性
         * 
         * 
@param attrs
         *            属性列表
         * 
@param attrName
         *            需要获取的属性
         * 
@return 返回获取的属性值
         * 
@throws NamingException
         
*/

        
private String getAttribute(Attributes attrs, String attrName)
                
throws NamingException {
            Attribute attr 
= attrs.get(attrName);
            
// 若没有指定的属性返回空字符串
            if (attr == null{
                
return "";
            }
 else {
                
return (String) attr.get();
            }

        }


        
/**
         * 从属性列表中获取指定的属性的所有属性值
         * 
         * 
@param attrs
         *            属性列表
         * 
@param attrName
         *            需要获取的属性
         * 
@return 返回获取的属性值
         * 
@throws NamingException
         
*/

        
private List<String> getMoreSameAttributes(Attributes attrs,
                String attrName) 
throws NamingException {

            Attribute attr 
= attrs.get(attrName);
            List
<String> elelist = new ArrayList<String>();
            
// 若没有指定的属性返回null
            if (attr == null{
                
return null;
            }
 else {
                
// 获取当前属性的所有值,添加到返回列表中
                Enumeration ent = attr.getAll();
                
while (ent.hasMoreElements())
                    elelist.add(ent.nextElement().toString());
                
return elelist;
            }

        }

    }


    
private void dispPerson(LdapPersonInfo temp) {
        System.out.println(
"-----------------------------");
        System.out.println(
"User(uid: " + temp.getUid() + ") listing...");
        System.out.println(
"First Name: " + temp.getFirstName());
        System.out.println(
"Last Name: " + temp.getLastName());
        System.out.println(
"Common Name: " + temp.getCn());
        System.out.println(
"User ID: " + temp.getUid());
        System.out.println(
"E-Mail: " + temp.getMail());
        System.out.println(
"Phone: " + temp.getTelephone());
        System.out.println(
"Fax: " + temp.getFax());
        System.out.println(
"List completed.");
        System.out.println(
"-----------------------------n");
    }


    
public static void main(String[] str) {
        ApplicationContext context 
= new ClassPathXmlApplicationContext(
                
"applicationContext.xml");
        UserDaoLdapImpl test 
= (UserDaoLdapImpl) context.getBean("userDao");
        System.out.println(test.userLogin(
"lisi""123"));

    }


}

原文地址:https://www.cnblogs.com/weipeng/p/3342245.html