本篇文章面向的群体主要为已经有LDAP的环境并且已经完成部署的开发人猿,不会过多阐述LDAP的机制、原理等

当我们成功连接到LDAP的时候 此时我们一定拥有以下两个条件

1.dc=你的公司名,dc=com //个人理解,这个代表LDAP的域名,叫什么并不重要

2.

一个manager账号 //算是一个管理员用户

我们使用ldap工具先手动创建一个ou (类似与window系统里的文件夹)

objectClass 就是这个单位所需要的模板 选择organizationalUnit

Java ldap 用户密码解密 java ldap统一用户认证_Java ldap 用户密码解密

我这里起名叫users (也可以使用代码创建,不过复用性较小,我这里手动创建的)

Java ldap 用户密码解密 java ldap统一用户认证_LDAP_02

这个ou里面存放所有的人员信息

接下来我们转移到JAVA上 使用JAVA和LDAP建立连接

首先创建一个LDAP工具类 LdapUtils(名字随意)

创建几个常量

//完全没有外部jar的引入 都是JDK 8 自带的jar
    //这里更换为ldap的连接地址
    private static final String URL = "ldap://192.168.26.121:389/";
    // dc=company是你的公司名,就是前面提到的
    private static final String BASEDN = "ou=users,dc=company,dc=com";
    //引入ldap提供的jar
    private static final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    //javax naming 包提供的ldap连接器
    private static LdapContext ctx = null;
    //也是javax 提供的 应该是用来存储数据的
    private static final Control[] connCtls = null;

然后我们尝试连接LDAP

public static void main(String[] args) {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
        env.put(Context.PROVIDER_URL, URL + BASEDN);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        //这个root账号需要根据开头提到的账号修改一下 格式不要乱
        String root = "cn=manager,dc=company,dc=com";
        env.put(Context.SECURITY_PRINCIPAL, root);   // 管理员
        env.put(Context.SECURITY_CREDENTIALS, "123456");  // 管理员密码
        try {
            ctx = new InitialLdapContext(env, connCtls);
            System.out.println( "连接成功" );
        } catch (javax.naming.AuthenticationException e) {
            System.out.println("连接失败:");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("连接出错:");
            e.printStackTrace();
        }
    }

运行

Java ldap 用户密码解密 java ldap统一用户认证_LDAP_03

拥有了连接之后 我们就可以试着创建一个用户了

先写一个添加用户的方法

public static boolean addUser() {
        try {
            //attrsbu 用来存放数据 类似于map
            BasicAttributes attrsbu = new BasicAttributes();
            //创建用户objectclass 就是上面提到的模块
            BasicAttribute objclassSet = new BasicAttribute("objectclass");
            //第一个是基本适合大部分架构的用户通用模块
            objclassSet.add("inetOrgPerson");
            //第二个是需要绑定部门的 这里可以选择不使用 写这里是方便多模块的理解
            objclassSet.add("posixAccount");
            //将模块存进集合
            attrsbu.put(objclassSet);
            //cn 必填项 不可重复
            attrsbu.put("cn", "林色");
            //gidNumber 如果选择第二个模块是必填值 如果没选择不能填写 10086是部门id
            attrsbu.put("gidNumber", "10086");
            //homeDirectory个人主页 如果选择第二个模块必填值 和上一个同理
            attrsbu.put("homeDirectory", "/serleen");
            //同上 值随意
            attrsbu.put("sn", "10010");
            //同上 值必须为number
            attrsbu.put("uidNumber", "10010");
            //uid 一般作为唯一标识符 可选填 尽量不要重复 如果选择第二个模块必填
            attrsbu.put("uid", "serleen");
            //userPassword 密码 可不填 加密方式比较复杂 感兴趣可以自己去查相关资料
            attrsbu.put("userPassword","123456");
            //创建用户 存储到ldap时的唯一标识 可选uid 也可以选cn 也可以选很多很多
            ctx.createSubcontext("uid=serleen", attrsbu);
            System.out.println("添加用户成功");
            return true;
        } catch (NamingException ex) {
            ex.printStackTrace();
            System.out.println("添加用户失败");
        }
        return false;
    }

官方的建议是sn代表姓 cn代表名 我们可以不接受他的建议

任何字段的值都可以随意填写 只要我们自己清楚就可以(有个别字段有限制 例如密码,uidNumber)

我把刚才的连接代码写入了方法里 命名connLdap()

public static void main(String[] args) {
        connLdap();
        addUser();
    }

运行

Java ldap 用户密码解密 java ldap统一用户认证_Java ldap 用户密码解密_04

这时ou=users下 出现了一个新的用户 也就是我们刚才创建的用户

Java ldap 用户密码解密 java ldap统一用户认证_JAVA_05

有了添加 我们要查询一下试试呢?

写一个查询方法

public static void getUser(String uid) {
        try {
            SearchControls constraints = new SearchControls();
            //建立搜索引擎search所需要的对象
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration<SearchResult> en = ctx.search("","uid="+uid, constraints);
            if (en == null || !en.hasMoreElements()) {
                System.out.println("未找到该用户");
            }
            SearchResult sr = (SearchResult) en.next();// 得到符合搜索条件的DN
            Attributes attrs = sr.getAttributes();// 得到符合条件的属性集
            //可以用一下方式拿到想要的值
            System.out.println(attrs.get("cn").get().toString());
            System.out.println(attrs.get("uid").get().toString());
            System.out.println(attrs.get("userPassword").get().toString());
        } catch (Exception e) {
            System.out.println("查找用户时产生异常。");
            e.printStackTrace();
        }
    }

进行查询

public static void main(String[] args) {
        connLdap();
        getUser("serleen");
    }

得到结果

Java ldap 用户密码解密 java ldap统一用户认证_Java ldap 用户密码解密_06

[b@4d76f3f8就是加密过的密码

查询也有了 我们再来一个删除?

写一个删除方法

public static void deleteUser(String UID){
        String userDN ="uid="+ UID ;
        try {
            ctx.destroySubcontext(userDN);
            System.out.println("删除用户成功");
        } catch (NamingException e) {
            e.printStackTrace();
            System.out.println("删除用户失败");
        }
    }

非常的简单 我们执行一下

public static void main(String[] args) {
        connLdap();
        deleteUser("serleen");
    }

Java ldap 用户密码解密 java ldap统一用户认证_详解_07

Java ldap 用户密码解密 java ldap统一用户认证_Java ldap 用户密码解密_08