LDAP简介及Java、客户端连接

简介: LDAP简介及Java、客户端连接

一、概述:

1、简介

LDAP(Lightweight Directory Access Protocol)

LDAP代表轻型目录访问协议(Lightweight Directory Access Protocol)。顾名思义,它是用于访问目录服务的轻量级协议,特别是基于X.500协议的目录服务。LDAP运行于TCP/IP连接上或其他面向传输服务的连接上。LDAP是IETF标准跟踪协议,并且在“Lightweight Directory Access Protocol (LDAP) Technical Specification Road Map” RFC4510中进行了指定。

目录是专门为搜索浏览而设计的专用数据库,支持基本的查找和更新功能。

提供目录服务的方式有很多。不同的方法允许将不同类型的信息存储在目录中,对如何引用,查询和更新该信息,如何防止未经授权的访问等提出不同的要求(这些由LDAP定义)。一些目录服务是本地的,提供本地服务;一些目录服务是全球性的,向更广泛的环境(例如,整个Internet)提供服务。全局服务通常是分布式的,这意味着它们包含的数据分布在许多机器上,所有这些机器协作以提供目录服务。通常,全局服务定义统一的名称空间,无论在何处访问,都可以提供相同的数据视图。

2、LDAP目录

2.1 基于国家的目录排列

在LDAP中,目录条目以树状分层结构排列。传统上,此结构反映了地理和组织边界。代表国家的条目显示在树的顶部。它们下面是代表省和国家机构的条目。再下一层可能是代表组织单位,人员,打印机,文档或您想到的几乎所有其他内容的条目

2.2 基于域名的排列

该树还可以基于网络域名进行排列。这种命名方法变得越来越流行,因为它允许使用DNS定位目录服务。

基于域名的LDAP目录树示例:

3、为什么使用LDAP

随着公司内部各种开源平台越来越多(例如:gitlab、Jenkins、Yapi等等),账号维护变成一个繁琐麻烦的事情,急需有一个统一的账号维护平台,一个人只需一个账号,在公司内部平台通用,而大多数开源平台都支持LDAP;因此只要搭建好LDAP服务,并跟钉钉之类的平台实现账号同步,即可实现统一账号管理;

二、Java连接代码

1、连接代码

现在可以从Java程序访问LDAP。 向您展示如何执行此操作的最佳方法是通过示例程序。 该程序将执行以下任务:

  • 创建一个新的LDAP对象
  • 查看LDAP对象
  • 将新属性添加到LDAP对象
  • 修改LDAP对象上的属性
  • 删除LDAP对象上的属性
  • 删除LDAP对象
package test;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.*;
public class LDAPTest {
    public void run() {
        try {
            DirContext context = getContext();
            String name = "employeeNumber=00001,ou=system";
            createLDAPObject(context, name);
            createAttribute(context, name, "displayName", "JOBS");
            viewAttribute(context, name, "displayName");
            updateAttribute(context, name, "displayName", "STEVE");
            viewAttribute(context, name, "displayName");
            removeAttribute(context, name, "displayName");
            removeLDAPObject(context, name);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
    private void removeLDAPObject(DirContext context, String name) throws NamingException {
        context.destroySubcontext(name);
    }
    private void createLDAPObject(DirContext context, String name) throws NamingException {
        Attributes attributes = new BasicAttributes();
        Attribute attribute = new BasicAttribute("objectClass");
        attribute.add("inetOrgPerson");
        attributes.put(attribute);
        Attribute sn = new BasicAttribute("sn");
        sn.add("Steve");
        attributes.put(sn);
        Attribute cn = new BasicAttribute("cn");
        cn.add("Jobs");
        attributes.put(cn);
        attributes.put("telephoneNumber", "123456");
        context.createSubcontext(name, attributes);
    }
    private void removeAttribute(DirContext context, String name, String attrName) throws NamingException {
        Attribute attribute = new BasicAttribute(attrName);
        ModificationItem[] item = new ModificationItem[1];
        item[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attribute);
        context.modifyAttributes(name, item);
    }
    private void createAttribute(DirContext context, String name, String attrName, Object attrValue) throws NamingException {
        Attribute attribute = new BasicAttribute(attrName, attrValue);
        ModificationItem[] item = new ModificationItem[1];
        item[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, attribute);
        context.modifyAttributes(name, item);
    }
    private void updateAttribute(DirContext context, String name, String attrName, Object attrValue) throws NamingException {
        Attribute attribute = new BasicAttribute(attrName, attrValue);
        ModificationItem[] item = new ModificationItem[1];
        item[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attribute);
        context.modifyAttributes(name, item);
    }
    private void viewAttribute(DirContext context, String name, String attrName) throws NamingException {
        Attributes attrs = context.getAttributes(name);
        System.out.println(attrName + ":" + attrs.get(attrName).get());
    }
    private DirContext getContext() throws NamingException {
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        properties.put(Context.PROVIDER_URL, "ldap://localhost:10389");
        return new InitialDirContext(properties);
    }
    public static void main(String[] args) {
        new LDAPTest().run();
    }
}

2、LDAP登录的三种方式

搜索中关于java 登录ldap,大部分会采用 cn=xxx,ou=xxx,dc=xxx的方式,此处的cn是用户的Display Name,而不是account,而且如果ou有多层,比如我们的OU就会超过三层。

那最好是通过用户的account直接登录

package com.lydms.demospringtransaction.controller;
//package test;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;
public class LDAPTest {
    /**
     * 获取默认LDAP连接     * Exception 则登录失败,ctx不为空则登录成功
     * @return void
     */
    public static LdapContext getLDAPConnection() throws AuthenticationException, CommunicationException,Exception {
        LdapContext ctx = null;
        //LDAP 连接地址 ldap://IP:PORT (default port 389)
        String LDAP_URL = "";
        //LDAP SSL连接地址 ldaps://IP:PORT (default port 636)
        //(这个用起来比较麻烦,目前知道管理员改密码必须使用SSL)
        String LDAP_SSL_URL = "";
        //用户名
        String userAccount = "";
        //管理员密码
        String userPassword = "";
//      方式1
//      基于姓名(cn),此cn为Display Name,部门有同名就麻烦了
        userAccount = "cn=xxx,OU=xxx,DC=xxx,DC=com";
//        方式2
//        基于Account User Logon name:
//      userAccount = "xxx@domain.xxx";
//        方式3
//        基于Account User Logon name(pre-windows 2000):
//        userAccount = "domain\\xxx"
//      基于登录名(uid (User ID)与 unix 的 uid 完全不同)(请注意objectSID,此处尝试失败)
//      uid=abc123, ou=xxxx, dc=xxxx, dc=com
        userPassword = "xxxxx";
        Hashtable<String,String> HashEnv = new Hashtable<String,String>();
        HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别(none,simple,strong)
        HashEnv.put(Context.SECURITY_PRINCIPAL, userAccount); //AD的用户名
        HashEnv.put(Context.SECURITY_CREDENTIALS, userPassword); //AD的密码
        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
        HashEnv.put("com.sun.jndi.ldap.connect.timeout", "3000");//连接超时设置为3秒
        HashEnv.put(Context.PROVIDER_URL, LDAP_URL);
        ctx =  new InitialLdapContext(HashEnv, null);//new InitialDirContext(HashEnv);// 初始化上下文
        return ctx;
    }
}

三、客户端下载

LdapBrowser客户端:

https://download.csdn.net/download/weixin_44624117/87780021

四、参考地址

1、LDAP介绍及使用

https://blog.csdn.net/suo082407128/article/details/115294490

2、Java到LDAP教程(包括如何安装LDAP服务器/客户端)

https://blog.csdn.net/dnc8371/article/details/106703325

3、JAVA中使用LDAP登录的三种方式

https://www.cnblogs.com/huanghongbo/p/12053272.html

五、官方地址

1、LDAP地址:

OpenLDAP(LDAP开源实现)官方文档库:https://www.openldap.org/doc/

LDAP管理员指南:https://www.openldap.org/doc/admin24/index.html

非OpenLDAP官方Docker镜像:https://github.com/osixia/docker-openldap

2、LDAP Account Manager 地址:

OpenLDAP安装完成后,用命令操作不方便,需要一个可视化管理工具随时访问,LDAP Account Manager为web版的管理工具;

官网:https://www.ldap-account-manager.org/lamcms/

官网Demo:https://www.ldap-account-manager.org/lam/templates/login.php,密码lam

官方docker镜像:https://registry.hub.docker.com/r/ldapaccountmanager/lam

目录
相关文章
|
1月前
|
存储 Java 关系型数据库
高效连接之道:Java连接池原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。频繁创建和关闭连接会消耗大量资源,导致性能瓶颈。为此,Java连接池技术通过复用连接,实现高效、稳定的数据库连接管理。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接池的基本操作、配置和使用方法,以及在电商应用中的具体应用示例。
62 5
|
1月前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
47 3
|
1月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
41 4
|
2月前
|
Java 关系型数据库 MySQL
如何用java的虚拟线程连接数据库
本文介绍了如何使用Java虚拟线程连接数据库,包括设置JDK版本、创建虚拟线程的方法和使用虚拟线程连接MySQL数据库的示例代码。
57 6
如何用java的虚拟线程连接数据库
|
1月前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
30 1
|
1月前
|
Java 数据库连接 数据库
Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销
本文深入探讨了Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销,显著提升了系统的响应速度和吞吐量。文章介绍了连接池的工作原理,并以HikariCP为例,展示了如何在Java应用中使用连接池。通过合理配置和优化,连接池技术能够有效提升应用性能。
46 1
|
2月前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
|
3月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
2月前
|
SQL 存储 Java
Java中使用ClickHouseDriver连接和基本操作
通过上述步骤,你可以轻松地在Java应用中集成ClickHouse数据库,执行基本的CRUD操作。需要注意的是,实际开发中应当根据实际情况调整数据库连接配置(如URL中的主机、端口、数据库名等),并根据应用需求选择合适的异常处理策略,确保代码的健壮性和资源的有效管理。此外,对于复杂查询和大批量数据处理,建议充分利用ClickHouse的特性(如分布式处理、列式存储优化等),以进一步提升性能。
142 2
|
2月前
|
分布式计算 Java Hadoop
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
67 1