文档章节

LDAP调研日志

d
 devils_os
发布于 2019/10/21 16:15
字数 1849
阅读 82
收藏 0

Springboot+LDAP调研日志

LDAP

(一)概念

LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单得多并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。以上内容来源于百度百科

(二)企业级LDAP场景

  1. 难题
    每个企业在运行过程中,会使用邮箱、考勤、CRM、ERP等系统,每个系统都需要账号去登录认证,每一个新员工入职的时候,HR需要为其开通好多个系统账号,一方面,需要开通的账号比较多,员工离职的时候再挨个去将这些账号冻结,增加了HR的工作量;另一方面,员工自己拥有这么多账号和密码,管理起来也不是很方便,聪明的需要做一个personInfo.txt去维护了。
    这个时候搭建一个统一的账号认证中心,使用一个账号,可以到处登录,然后在每个系统中去分配不同的权限即可,这样就可以解决上述两个问题。

  2. 为什么用LDAP认证

  • 是对读操作进行优化的种数据库,读操作效率高。
  • 可以灵活的改变数据类型,增加字段不会影响到查询。
  • LDAP是个开放的标准协议,提供所有的程序语言的标准API接口
  • 由于LDAP数据库的数据存储是树结构,分支可以单独放到单台服务器,能够支持分布式、负载均衡、跨域等
  • LDAP支持强认证方式,可以达到很高的安全别。在国际化方面,LDAP使用了UTF-8编码来存储各种语言的字符

搭建OpenLDAP

先上官网链接 http://www.openldap.org/ 本人是在docker中启动的,如果选择在linux中启动,可以参考 https://yq.aliyun.com/articles/549058 这篇帖子

docker方式启动

如果对docker命令不是特别熟悉,本人自己另一篇帖子可供简单了解 https://www.jianshu.com/p/af7977b1075c

  1. 拉取镜像
 docker pull osixia/openldap:1.2.2
  1. 启动镜像
docker run -p 389:389 -p 689:689 --name my-openldap \
 --env LDAP_ORGANISATION="my-company" --env LDAP_DOMAIN="my-company.com" --env LDAP_ADMIN_PASSWORD="123456" --detach osixia/openldap:1.2.2
  1. 查看
docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                      PORTS                                                 NAMES
d90a057443b0        osixia/openldap:1.2.2   "/container/tool/run"    47 hours ago        Up 47 hours                 0.0.0.0:389->389/tcp, 0.0.0.0:689->689/tcp, 636/tcp   my-openldap

可以看到我已经启动成功,映射出两个端口,389和689,我们的主要操作就在389上

  1. 使用客户端工具进行连接
    下载地址:http://directory.apache.org/studio

    ConnectionName 是自己给这个连接起个容易记住的名字
    Hostname 是自己服务器IP地址,我是本地启动的
    Port 是端口,默认都是389

    AuthenticationMethod : Simple Authentication 简单验证
    Bind DN or User: cn=admin,dc=my_company,dc=com 之前设置的管理员用户名
    Bind Password :设置的管理员密码

LDAP相关概念

  1. 简写含义
属性 含义 举栗子
c Country国家 c=chinese
dc DomainComponent,常用来指一个域名的一部分 dc=my_company,dc=com
cn CommonName,一个对象的名字,如果指人,使用全名 cn=calvin
ou OrganizationalUnit 一个组织单元的名字 ou = bj_develop(北京研发部)
sn Surname,一个人的姓 sn=赵、钱、孙、李
uid Userid,某个用户的登录名,与Linux系统中用户的uid不同 给一个唯一的ID
o Organization 组织的名字 o=develop
  1. 核心Attribute
名称 描述 必要属性
domain
organization o
organizationalUnit ou
person sn,cn
organizationPerson cn,sn
top 抽象型,顶级ObjectClass
posixAccount Linux用户 cn,gidNumber,homeDirectory,uid,uidNumber
posixGroup Linux用户组 cn,gidNumber

以上资料来源https://cloud.tencent.com/developer/article/1444535

Springboot整合LDAP

经过上面的安装,我们就算是成功启动了一个OpenLdap的服务,环境准备好了,接下来正式开始搭建项目

项目核心类构建

  1. pom.xml
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.14.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.calvin.ldap</groupId>
    <artifactId>ldap-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ldap-test</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- LDAP 相关配置-->
        <dependency>
            <groupId>org.springframework.ldap</groupId>
            <artifactId>spring-ldap-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>ldapbp</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

  1. application.yml
calvin:
  ldap:
    url: 'ldap://127.0.0.1:389'
    base: 'dc=my-company,dc=com'
    user_dn: 'cn=admin,dc=my-company,dc=com'
    password: '123456'
  1. LdapConfigruation.java
/**
 * <p>
 *     LDAP配置类
 * </p>
 * @author Calvin
 * @date 2019/10/14
 * @since 1.0
 */
@Configuration
public class LdapConfiguration {

    /**
     * 服务器地址
     */
    @Value("${calvin.ldap.url}")
    private String ldapUrl;

    /**
     * 公司、部门
     */
    @Value("${calvin.ldap.base}")
    private String baseDC;

    /**
     * 管理员用户
     */
    @Value("${calvin.ldap.user_dn}")
    private String ldapUser;

    /**
     * 管理员密码
     */
    @Value("${calvin.ldap.password}")
    private String ldapPassword;

    /**
     * LDAP环境配置
     * @return
     */
    @Bean
    public LdapContextSource ldapContextSource(){
        LdapContextSource source = new LdapContextSource();

        Map<String, Object> config = new HashMap<>();
        config.put("java.naming.ldap.attributes.binary", "objectGUID");

        source.setUrl(ldapUrl);
        source.setBase(baseDC);
        source.setPassword(ldapPassword);
        source.setUserDn(ldapUser);
        source.setPooled(true);
        source.setBaseEnvironmentProperties(config);

        return source;
    }

    /**
     * LDAP操作类的Bean定义
     * @return
     */
    @Bean
    public LdapTemplate ldapTemplate(){
        LdapTemplate ldapTemplate = new LdapTemplate();
        ldapTemplate.setContextSource(ldapContextSource());
        return ldapTemplate;
    }
}

  1. JSONObjectMapper.java
/**
 * <p>
 *     JSONObjectMapper,转换类,将Attributes转换成一个JSONObject方便接收打印
 * </p>
 *
 * @author Calvin
 * @date 2019/10/17
 * @since
 */
public class JSONObjectMapper implements AttributesMapper<JSONObject> {
    @Override
    public JSONObject mapFromAttributes(Attributes attributes) throws NamingException {
        NamingEnumeration<? extends Attribute> all = attributes.getAll();
        JSONObject jsonObject = new JSONObject();
        while (all.hasMore()){
            Attribute next = all.next();
            jsonObject.put(next.getID(),next.get());
        }
        return jsonObject;
    }
}
  1. LdapTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class LdapTest {

    @Autowired
    private LdapTemplate ldapTemplate;

}

测试和简单调用API

  1. 先查询一下admin用户,确保配置正确
/**
 * 查询一下Admin用户
 */
@Test
public void test1() {
    AndFilter filter = new AndFilter();
    filter.and(new EqualsFilter("cn", "admin"));
    List search = ldapTemplate.search("", filter.encode(), new JSONObjectMapper());
    search.forEach(System.out::println);
}

2-1
上图中显示已经能正常查询admin用户,所以确定配置正确

  1. 开始创建一个组
/**
     * 添加一个组织
     */
    @Test
    public void test2(){
        BasicAttributes attributes = new BasicAttributes();
        BasicAttribute objectClass = new BasicAttribute("objectClass");
        objectClass.add("organizationalUnit");
        objectClass.add("top");
        attributes.put(objectClass);
        attributes.put("description","this is develop dept");
        LdapNameBuilder nameBuilder = LdapNameBuilder.newInstance();
        nameBuilder.add("ou","develop");
        ldapTemplate.bind(nameBuilder.build(),null, attributes);
    }

通过工具查看,就可以看到我们的组织已经添加好了

  1. 在这个组中添加一个员工
/**
 * 增加一个员工
 */
@Test
public void test3(){
    //设置objectClass
    BasicAttribute objectClass = new BasicAttribute("objectClass");
    objectClass.add("top");
    objectClass.add("person");
    objectClass.add("inetOrgPerson");
    objectClass.add("organizationalPerson");
    Attributes attr = new BasicAttributes();
    attr.put(objectClass);
    //设置其他属性
    attr.put("cn", "Jack");
    attr.put("sn", "Ma");
    attr.put("description", "this is first Employee");
    attr.put("userPassword", DigestUtils.md5DigestAsHex("123456".getBytes()));
    attr.put("telephoneNumber", "138 8888 8888");
    //设置dn
    LdapNameBuilder nameBuilder = LdapNameBuilder.newInstance();
    nameBuilder.add("ou","develop");
    nameBuilder.add("uid","0000001");
    //bind方法即是添加一条记录。
    ldapTemplate.bind(nameBuilder.build(), null, attr);
}

工具客户端查看,员工已经添加成功
接下来我们更换uid和cn,sn,多增加几个员工

  1. 使用代码查询员工列表
/**
 * 查询develop部门下的员工
 */
@Test
public void test4(){
    AndFilter filter = new AndFilter();
    filter.and(new EqualsFilter("objectClass", "person"));
    LdapQueryBuilder queryBuilder = LdapQueryBuilder.query();
    List search = ldapTemplate.search(queryBuilder.base("ou=develop").filter(filter), new JSONObjectMapper());
    search.forEach(System.out::println);
}

  1. 使用创建的用户登录
 /**
  * 尝试登陆
  */
 @Test
 public void test5(){
     AndFilter filter = new AndFilter();
     filter.and(new EqualsFilter("objectClass", "person"));
     boolean isSuccess = ldapTemplate.authenticate("uid=0000001,ou=develop",
             filter.encode(), DigestUtils.md5DigestAsHex("123456".getBytes()));
     System.out.println(isSuccess);
 }

更多关于LdapTemplate相关的API参考官网 https://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/core/LdapTemplate.html

总结

  1. 了解LDAP的基本概念,进行基本的安装搭建
  2. 使用Springboot集成了ldap的API,并对照进行了API简单尝试
  3. 本文参考相当多的博客,相关连接已经都贴到了文中,如有侵权,请联系我
  4. 首次接触LDAP,欢迎大家多多留言指正

© 著作权归作者所有

d
粉丝 0
博文 19
码字总数 33268
作品 0
昌平
后端工程师
私信 提问
加载中

评论(0)

ldap配置系列三:grafana集成ldap

ldap配置系列三:grafana集成ldap grafana的简介 grafana是一个类似kibana的东西,是对来自各种数据源的数据进行实时展示的平台,拥有这牛逼的外观。给一个官方的demo体验地址: https://pl...

LinuxPanda
2018/09/06
0
0
Docker 私有仓库方案比较与搭建

我们知道docker镜像可以托管到dockerhub中,跟代码库托管到github是一个道理。但如果我们不想把docker镜像公开放到dockerhub中,只想在部门或团队内部共享docker镜像,能不能项gitlab一样在搭...

jaazz
2018/07/19
0
0
CentOS 6.9下OpenLDAP 的安装与配置

LDAP 基础教程 LDAP 全称轻量级目录访问协议(英文:Lightweight Directory Access Protocol),是一个运行在 TCP/IP 上的目录访问协议。LDAP实现提供被称为目录服务的信息服务,可以看做是一...

898009427
2018/07/31
0
0
调度系统Airflow1.10.4调研与介绍和docker安装

Airflow1.10.4介绍与安装 现在是9102年,8月中旬。airflow当前版本是1.10.4. 随着公司调度任务增大,原有的,基于crontab和mysql的任务调度方案已经不太合适了,需要寻找一个可以支持分布式扩...

Ryan.Miao
2019/08/26
0
0
cent OS 6.3 yum方式安装openldap,phppldapadmin,lam

主目录http://407711169.blog.51cto.com/6616996/1439944 其实如果不是对ldap各种参数要求都十分严格的情况下,比较建议采用yum的方式安装。因为相关依赖环境,功能都十分全面。对于初学者,...

陈延宗
2014/07/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

植物:君子兰

ylbtech-植物:君子兰 君子兰(学名: Clivia miniata),别名 剑叶石蒜、大叶石蒜,是 石蒜科 君子兰属的 多年生草本植物,属观赏 花卉,原产于 南非南部。 花期长达30-50天,以冬春为主,元...

osc_gp8avabl
22分钟前
31
0
植物:玉簪

ylbtech-植物:玉簪 玉簪(学名: Hosta plantaginea (Lam.) Aschers.),又名 白萼、白鹤仙,是 百合科,玉簪属的 多年生宿根植物。叶基生,成簇,卵状心形、卵形或卵圆形。 花葶高40-80...

osc_1psr53ow
23分钟前
41
0
植物:迎春花

ylbtech-植物:迎春花 迎春花(学名: Jasminum nudiflorum Lindl. ):别名 迎春、黄素馨、金腰带,落叶 灌木丛生。株高30-500厘米。小枝细长直立或拱形下垂,呈纷披状。3小叶复叶交互对生,...

osc_fscujk71
24分钟前
38
0
植物:雪铁芋

ylbtech-植物:雪铁芋 雪铁芋(学名: Zamioculcas zamiifolia Engl.),又名为 金钱树。是多年生常绿 草本植物,是极为少见的带地下 块茎的观叶植物。地上部无主茎,不定芽从块茎萌发形成大...

osc_47qtuhkb
25分钟前
27
0
Java之关键字的使用

java中有很多的关键字,他们的使用让Java语言变得更加灵活、易用,下面将介绍Java中最常用的几个关键字并说明其用法。 关键字:return 1.使用范围: 使用在方法体中 2.作用: ① 结束方法 ②...

RealBruce
26分钟前
34
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部