Spring LDAP Object Directory Mapping (ODM) Configuration Example

摘要: In the following tutorial we demonstrate how to use Spring LDAP Object Directory Mapping (ODM). ODM offers developers the ability to use annotations to map LDAP directories to Java objects.

In the following tutorial we demonstrate how to use Spring LDAP Object Directory Mapping (ODM). ODM offers developers the ability to use annotations to map LDAP directories to Java objects.

Maven Dependencies

We use Apache Maven to manage our project dependencies. Add the following dependencies to your project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.memorynotfound.ldap</groupId>
    <artifactId>attributes-mapper</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <url>https://memorynotfound.com</url>
    <name>Spring LDAP - ${project.artifactId}</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-ldap</artifactId>
        </dependency>
        <dependency>
            <groupId>com.unboundid</groupId>
            <artifactId>unboundid-ldapsdk</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Configure Embedded LDAP Server using application.yml

We use spring boot to create and configure our embedded LDAP server. The following properties create an LDAP server running on port 12345 and populates the LDAP server using the schema.ldif which resides on the class-path.

# Spring LDAP CRUD Operations Binding and Unbinding Example

spring:
  ldap:

    # Spring LDAP
    #
    # In this example we use an embedded ldap server. When using a real one,
    # you can configure the settings here.
    #
    # urls: ldap://localhost:12345
    # base: dc=memorynotfound,dc=com
    # username: uid=admin
    # password: secret

    # Embedded Spring LDAP
    embedded:
      base-dn: dc=memorynotfound,dc=com
      credential:
        username: uid=admin
        password: secret
      ldif: classpath:schema.ldif
      port: 12345
      validation:
        enabled: false

Populate LDAP Server

The LDAP servers gets populated using the following schema.ldif file.

dn: dc=memorynotfound,dc=com
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: memorynotfound

# Organizational Units
dn: ou=groups,dc=memorynotfound,dc=com
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=people,dc=memorynotfound,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people

# Create People
dn: uid=john,ou=people,dc=memorynotfound,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: John Doe
sn: John
uid: john
password: secret

dn: uid=jihn,ou=people,dc=memorynotfound,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Jihn Die
sn: Jihn
uid: jihn
password: secret

dn: uid=jahn,ou=people,dc=memorynotfound,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Jahn Dae
sn: Jahn
uid: jahn
password: secret

# Create Groups
dn: cn=developers,ou=groups,dc=memorynotfound,dc=com
objectclass: top
objectclass: groupOfUniqueNames
cn: developers
ou: developer
uniqueMember: uid=john,ou=people,dc=memorynotfound,dc=com
uniqueMember: uid=jihn,ou=people,dc=memorynotfound,dc=com

dn: cn=managers,ou=groups,dc=memorynotfound,dc=com
objectclass: top
objectclass: groupOfUniqueNames
cn: managers
ou: manager
uniqueMember: uid=jahn,ou=people,dc=memorynotfound,dc=com

Annotations

  • @Entry – Class level annotation indicating the objectClass definitions to which the entity maps. (required)
  • @Id – Indicates that entity distinguished name (DN); the field declaring this attribute must be a derivative of the javax.naming.Name class. (required)
  • @Attribute – Indicates the mapping of a directory attribute to the object class field.
  • @DnAttribute – Indicates the mapping of a dn attribute to the object class field.
  • @Transient – Indicates the field is not persistent and should be ignored by the OdmManager.

The @Entry and @Id annotations are required to be declared on managed classes. @Entry is used to specify which object classes the entity maps to and (optionally) the directory root of the LDAP entries represented by the class. All object classes for which fields are mapped are required to be declared. Note that when creating new entries of the managed class, only the declared objectlasses will be used.

In order for a directory entry to be considered a match to the managed entity, all object classes declared by the directory entry must match be declared by in the @Entry annotation. For example: let’s assume that you have entries in your LDAP tree that have the objectclasses inetOrgPerson,organizationalPerson,person,top. If you are only interested in changing the attributes defined in the person objectclass, your @Entry annotation can be @Entry(objectClasses = { "person", "top"}). However, if you want to manage attributes defined in the inetOrgPerson objectclass you’ll need to use the full monty: @Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" }).

Managing LDAP Users

First, lets look at how to create, update and delete some users. We use the Person class to represent a person LDAP entry. This object is mapped with specific ODM annotations, mapping the object to the LDAP counterpart.

package com.memorynotfound.ldap;

import org.springframework.ldap.odm.annotations.*;
import org.springframework.ldap.support.LdapNameBuilder;
import javax.naming.Name;

@Entry(objectClasses = { "person", "top" })
public final class Person {

    private static final String BASE_DN = "dc=memorynotfound,dc=com";

    @Id
    private Name dn;

    @DnAttribute(value="uid")
    private String uid;

    @Attribute(name="cn")
    private String fullName;

    @Attribute(name="sn")
    private String lastName;

    @DnAttribute(value="ou")
    @Transient
    private String group;

    public Person() {
    }

    public Person(String fullName, String lastName) {
        Name dn = LdapNameBuilder.newInstance(BASE_DN)
                .add("ou", "people")
                .add("uid", fullName)
                .build();
        this.dn = dn;
        this.fullName = fullName;
        this.lastName = lastName;
    }

    public String getUid() {
        return uid;
    }

    public Name getDn() {
        return dn;
    }

    public void setDn(Name dn) {
        this.dn = dn;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    @Override
    public String toString() {
        return "Person{" +
                "dn=" + dn +
                ", uid='" + uid + '\'' +
                ", fullName='" + fullName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", group='" + group + '\'' +
                '}';
    }
}

By using annotations, our queries are simplified a lot. The following PersonRepository manages the basic CRUD operations performed on the LDAP server. These operations include but are not limited to: Create, Read, Update and Delete.

package com.memorynotfound.ldap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import static org.springframework.ldap.query.LdapQueryBuilder.query;

@Service
public class PersonRepository {

    @Autowired
    private LdapTemplate ldapTemplate;

    public Person create(Person person) {
        ldapTemplate.create(person);
        return person;
    }

    public Person findByUid(String uid) {
        return ldapTemplate.findOne(query().where("uid").is(uid), Person.class);
    }

    public void update(Person person) {
        ldapTemplate.update(person);
    }

    public void delete(Person person) {
        ldapTemplate.delete(person);
    }

    public List<Person> findAll() {
        return ldapTemplate.findAll(Person.class);
    }

    public List<Person> findByLastName(String lastName) {
        return ldapTemplate.find(query().where("sn").is(lastName), Person.class);
    }
}

Managing LDAP Groups

Now we are looking into managing our groups. We can map the Group object to the LDAP counterpart using Spring ODM Annotations.

package com.memorynotfound.ldap;

import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.support.LdapNameBuilder;

import javax.naming.Name;
import java.util.HashSet;
import java.util.Set;

@Entry(objectClasses = {"top", "groupOfUniqueNames"}, base = "cn=groups")
public final class Group {

    private static final String BASE_DN = "dc=memorynotfound,dc=com";

    @Id
    private Name dn;

    @Attribute(name="cn")
    @DnAttribute("cn")
    private String name;

    @Attribute(name="uniqueMember")
    private Set members;

    public Group() {
    }

    public Group(String name, Set members) {
        Name dn = LdapNameBuilder.newInstance(BASE_DN)
                .add("ou", "groups")
                .add("cn", name)
                .build();
        this.dn = dn;
        this.name = name;
        this.members = members;
    }

    public Group(Name dn, String name, Set members) {
        this.dn = dn;
        this.name = name;
        this.members = members;
    }

    public Name getDn() {
        return dn;
    }

    public void setDn(Name dn) {
        this.dn = dn;
    }

    public Set getMembers() {
        return members;
    }

    public void setMembers(Set members) {
        this.members = members;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void addMember(Name member) {
        if (this.members == null){
            this.members = new HashSet<>();
        }
        members.add(member);
    }

    public void removeMember(Name member) {
        members.remove(member);
    }

    @Override
    public String toString() {
        return "Group{" +
                "dn=" + dn +
                ", name='" + name + '\'' +
                ", members=" + members +
                '}';
    }
}

By using annotations, our queries are simplified a lot. The following GroupRepository manages the basic CRUD operations performed on the LDAP server. These operations include but are not limited to: Create, Read, Update and Delete.

package com.memorynotfound.ldap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import static org.springframework.ldap.query.LdapQueryBuilder.query;

@Service
public class GroupRepository {

    @Autowired
    private LdapTemplate ldapTemplate;

    public Group create(Group group) {
        ldapTemplate.create(group);
        return group;
    }

    public Group findBy(String attr, String value) {
        return ldapTemplate.findOne(query().where(attr).is(value), Group.class);
    }

    public void update(Group group) {
        ldapTemplate.update(group);
    }

    public void delete(Group group) {
        ldapTemplate.delete(group);
    }

    public List<Group> findAll() {
        return ldapTemplate.findAll(Group.class);
    }

}

Spring LDAP Object Directory Mapping (ODM) Configuration Example

We bootstrap our application using spring boot. After the application is initialized, we execute some operations on the LDAP server to demonstrate our previous code.

package com.memorynotfound.ldap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;
import java.util.List;

@SpringBootApplication
public class Application {

    private static Logger log = LoggerFactory.getLogger(Application.class);

    @Autowired private PersonRepository personRepository;
    @Autowired private GroupRepository groupRepository;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @PostConstruct
    public void init() {
        log.info("Spring LDAP Object Directory Mapping (ODM) Configuration Example");

        log.info("- - - - - Managing LDAP persons using Spring LDAP ODM");

        List<Person> persons = personRepository.findAll();
        log.info("persons: " + persons);

        Person olivier = new Person("Olivier Sips", "Sips");
        personRepository.create(olivier);

        Person john = personRepository.findByUid("john");
        personRepository.delete(john);

        Person jahn = personRepository.findByUid("jahn");
        jahn.setLastName("custom last name");
        personRepository.update(jahn);

        List<Person> result = personRepository.findByLastName("custom last name");
        log.info("result: " + result);

        persons = personRepository.findAll();
        log.info("persons: " + persons);

        log.info("- - - - - Managing LDAP groups using Spring LDAP ODM");

        List<Group> groups = groupRepository.findAll();
        log.info("groups: " + groups);

        Group otherEmployees = new Group("other employees", null);
        otherEmployees.addMember(jahn.getDn());
        groupRepository.create(otherEmployees);

        Group developers = groupRepository.findBy("cn", "developers");
        developers.removeMember(john.getDn());
        groupRepository.update(developers);

        Group managers = groupRepository.findBy("cn", "managers");
        groupRepository.delete(managers);

        groups = groupRepository.findAll();
        log.info("groups: " + groups);

        System.exit(-1);
    }


}

Output

The previous application will print the following output to the console.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.7.RELEASE)

2017-10-02 15:55:52.115  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : Spring LDAP Object Directory Mapping (ODM) Configuration Example
2017-10-02 15:55:52.115  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : - - - - - Managing LDAP persons using Spring LDAP ODM
2017-10-02 15:55:52.190  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : persons: [Person{dn=uid=jahn,ou=people,dc=memorynotfound,dc=com, uid='jahn', fullName='Jahn Dae', lastName='Jahn', group='people'}, Person{dn=uid=jihn,ou=people,dc=memorynotfound,dc=com, uid='jihn', fullName='Jihn Die', lastName='Jihn', group='people'}, Person{dn=uid=john,ou=people,dc=memorynotfound,dc=com, uid='john', fullName='John Doe', lastName='John', group='people'}]
2017-10-02 15:55:52.213  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : result: [Person{dn=uid=jahn,ou=people,dc=memorynotfound,dc=com, uid='jahn', fullName='Jahn Dae', lastName='custom last name', group='people'}]
2017-10-02 15:55:52.216  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : persons: [Person{dn=uid=jahn,ou=people,dc=memorynotfound,dc=com, uid='jahn', fullName='Jahn Dae', lastName='custom last name', group='people'}, Person{dn=uid=jihn,ou=people,dc=memorynotfound,dc=com, uid='jihn', fullName='Jihn Die', lastName='Jihn', group='people'}, Person{dn=uid=Olivier Sips,ou=people,dc=memorynotfound,dc=com, uid='Olivier Sips', fullName='Olivier Sips', lastName='Sips', group='people'}]
2017-10-02 15:55:52.217  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : - - - - - Managing LDAP groups using Spring LDAP ODM
2017-10-02 15:55:52.223  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : groups: [Group{dn=cn=developers,ou=groups,dc=memorynotfound,dc=com, name='developers', members=[uid=john,ou=people,dc=memorynotfound,dc=com, uid=jihn,ou=people,dc=memorynotfound,dc=com]}, Group{dn=cn=managers,ou=groups,dc=memorynotfound,dc=com, name='managers', members=[uid=jahn,ou=people,dc=memorynotfound,dc=com]}]
2017-10-02 15:55:52.236  INFO 17488 --- [           main] com.memorynotfound.ldap.Application      : groups: [Group{dn=cn=developers,ou=groups,dc=memorynotfound,dc=com, name='developers', members=[uid=jihn,ou=people,dc=memorynotfound,dc=com]}, Group{dn=cn=other employees,ou=groups,dc=memorynotfound,dc=com, name='other employees', members=[uid=jahn,ou=people,dc=memorynotfound,dc=com]}]

Download

上一篇: Spring Boot + Spring LDAP Advanced LDAP Queries Example
下一篇: Spring LDAP CRUD Operations Binding and Unbinding Example
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号