LDAP目录服务器介绍

LDAP目录服务器介绍目录是一个专门为搜索和浏览而设计的数据库,它也支持简单的插入、删除、修改功能。你可以把它理解为我们传统使用的关系型数据库,但是他与我们的关系型数据库有着本质的区别,目录的存储结构类似于linux文件系统,他是一颗树(类似下图),由于它是为浏览和搜索而设计的,它的查询速度很快,相…

前言

本文介绍LDAP目录服务器的简单概念以及如何使用Java操作LDAP作目录服务器

正文

什么是目录服务器?

目录是一个专门为搜索和浏览而设计的数据库,它也支持简单的插入、删除、修改功能。你可以把它理解为我们传统使用的关系型数据库,但是他与我们的关系型数据库有着本质的区别,目录的存储结构类似于linux文件系统,他是一颗树(类似下图),由于它是为浏览和搜索而设计的,它的查询速度很快,相反插入速度较慢,它也不支持事务和回滚以及复杂的插入、更新功能。目录服务器可像关系型数据库一样对外提供数据服务,它可以是单机或集群式的。在集群式的架构中每个机器都拥有一致的数据备份。

LDAP目录服务器介绍

树中的每个节点称之为条目(Entry),目录服务是以条目为基础的,在上图的树型结构中,每个条目都有一个唯一的绝对名字Directory Name(DN)和相对名字rDN。每个条目具有一组属性,每个属性有一个key,每个key对应一个或多个value。具体每个条目有哪些属性由ObjectClass约束,也就是说每个条目通过赋予ObjectClass来规定其必须拥有的属性。

例如上图的babs条目中:

DN:uid=babs,ou=people,dc=example,dc=com

相对于ou=people,dc=example,dc=com 节点的rDN:uid=babs

ObjectClass:Person

什么是LDAP?

LDAP全称为Lightweight Directory Access Protocol(轻量级目录访问协议),客户端与目录服务器遵循LDAP协议来发生交互,比如说新增一个节点,查询某个节点的属性等等。

常见的LDAP目录服务器

与关系型数据库一样,LDAP目录服务器是一个概念,包含许多具体实现的产品,比如关系型数据库常见的有MySQL,Oracle等等。LDAP目录服务器也有常见的具体实现,比如:OpenLDAP,Active Directory(Microsoft)。本文以OpenLDAP为例介绍Java如何操作LDAP服务器。

什么时候使用LDAP目录服务器?

看到目前为止,你可能会觉得目录服务器貌似和关系型数据库服务器没有什么区别,到底什么时候该使用目录服务器呢?

使用目录服务器最常见的情况就是多系统间的集中用户管理,比如公司会使用OA,Confluence,gitlab,jira等等办公系统。如果每个系统都需要我们记住一个账号密码,那无疑是很费力的。通过使用LDAP目录服务器将多个应用的用户集中管理起来,每个应用都通过通用的LDAP协议与目录服务器通信,达到用户信息集中管理的目的。事实上很多的开源项目都支持LDAP用户认证(例如SuperSet,Hue等等)

代码示例

package richstonedt.com;

import com.novell.ldap.*;
import com.novell.ldap.util.Base64;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/** * 参考地址:http://www.micmiu.com/opensource/java-ldap-demo/ */
@Slf4j
public class App {

    private static  String ldapHost = "192.168.x.x";
    private static int ldapPort = 389;
    private static String ldapBindDN = "cn=Manager,dc=my-domain,dc=com";
    private static String ldapPassword = "123456";
    private static int ldapVersion = LDAPConnection.LDAP_V3;

    /** * 获取连接 * * @return A LDAP Connection * @throws LDAPException * @throws UnsupportedEncodingException */
    @SuppressWarnings("deprecation")
    private static LDAPConnection connection() throws UnsupportedEncodingException, LDAPException {
        try {
            LDAPConnection lc = new LDAPConnection();
            //获取连接
            lc.connect(ldapHost, ldapPort);
            //认证
            lc.bind(ldapVersion, ldapBindDN, ldapPassword.getBytes("UTF8"));
            log.info("连接LDAP服务器成功!");
            return lc;
        } catch (Exception e) {
            log.debug("LDAP服务器连接失败!");
            throw e;

        }
    }

    /** * 搜索某目录节点下所有节点及其属性 * @param DN 目录节点名 * @throws LDAPException * @throws UnsupportedEncodingException */
    public static void searchEntry(String DN) throws LDAPException, UnsupportedEncodingException {
        LDAPConnection conn = connection();
        try {
            LDAPSearchResults searchResults = conn.search(DN,
                    LDAPConnection.SCOPE_SUB, "objectClass=*", null, false);
            while (searchResults.hasMore()) {
                LDAPEntry nextEntry;
                try {
                    nextEntry = searchResults.next();
                } catch (LDAPException e) {
                    log.debug("Error: " + e);
                    if (e.getResultCode() == LDAPException.LDAP_TIMEOUT
                            || e.getResultCode() == LDAPException.CONNECT_ERROR) {
                        break;
                    } else {
                        continue;
                    }
                }
                log.info("DN :" + nextEntry.getDN());
                log.info("|---- Attributes list: ");
                LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
                Iterator<LDAPAttribute> allAttributes = attributeSet.iterator();
                while (allAttributes.hasNext()) {
                    LDAPAttribute attribute = allAttributes.next();
                    String attributeName = attribute.getName();

                    Enumeration<String> allValues = attribute.getStringValues();
                    if (null == allValues) {
                        continue;
                    }
                    while (allValues.hasMoreElements()) {
                        String value = allValues.nextElement();
                        if (!Base64.isLDIFSafe(value)) {
                            // base64 encode and then print out
                            value = Base64.encode(value.getBytes());
                        }
                        log.info("|---- ---- " + attributeName
                                + " = " + value);
                    }
                }
            }
        } finally {
            if (conn.isConnected()) {
                conn.disconnect();
            }
        }
    }

    /** * 新增一个目录节点 * @param baseDN * @param rDN * @param attribute * @throws UnsupportedEncodingException * @throws LDAPException */
    public static void addEntry(String baseDN, String rDN, Map<String, String> attribute) throws UnsupportedEncodingException, LDAPException {
        LDAPConnection conn = connection();
        try {
            LDAPAttributeSet attributeSet = new LDAPAttributeSet();
            for (Map.Entry<String, String> entry : attribute.entrySet()) {
                attributeSet.add(new LDAPAttribute(entry.getKey(), entry.getValue()));
            }
            String DN = rDN + "," + baseDN;
            conn.add(new LDAPEntry(DN, attributeSet));
        } finally {
            if (conn.isConnected())
                conn.disconnect();
        }
    }

    /** * 删除一个目录节点 * @param DN 目录节点名 * @throws UnsupportedEncodingException * @throws LDAPException */
    public static void deleteEntry(String DN) throws UnsupportedEncodingException, LDAPException {
        LDAPConnection conn = connection();
        try {
            conn.delete(DN);
        } finally {
            if (conn.isConnected()) {
                conn.disconnect();
            }
        }

    }

    public static void main(String[] args) throws UnsupportedEncodingException, LDAPException {
        //新增节点
        Map<String, String> map = new HashMap<>();
        map.put("objectclass", "inetOrgPerson");
        map.put("cn", "liuruojing");
        map.put("sn", "liuruojing");
        addEntry("ou=userAccount,dc=my-domain,dc=com", "uid=liuruojing", map);

        //查询节点
        searchEntry("uid=liuruojing,ou=userAccount,dc=my-domain,dc=com");

        //删除节点
        deleteEntry("uid=liuruojing,ou=userAccount,dc=my-domain,dc=com");

    }


}

注意:需要引入JLDAP的Maven依赖

<dependency>
      <groupId>com.novell.ldap</groupId>
      <artifactId>jldap</artifactId>
      <version>4.3</version>
      <type>jar</type>
      <scope>compile</scope>
</dependency>

今天的文章LDAP目录服务器介绍分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/14957.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注