Spring Boot中使用LDAP來統一管理使用者資訊實戰
一 LDAP簡介
LDAP(輕量級目錄訪問協議,Lightweight Directory Access Protocol)是實現提供被稱為目錄服務的資訊服務。目錄服務是一種特殊的資料庫系統,其專門針對讀取,瀏覽和搜尋操作進行了特定的優化。目錄一般用來包含描述性的,基於屬性的資訊並支援精細複雜的過濾能力。目錄一般不支援通用資料庫針對大量更新操作需要的複雜的事務管理或回捲策略。而目錄服務的更新則一般都非常簡單。這種目錄可以儲存包括個人資訊、web鏈結、jpeg影象等各種資訊。為了訪問儲存在目錄中的資訊,就需要使用執行在TCP/IP 之上的訪問協議—LDAP。
LDAP目錄中的資訊是是按照樹型結構組織,具體資訊儲存在條目(entry)的資料結構中。條目相當於關係資料庫中表的記錄;條目是具有區別名DN (Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN相當於關係資料庫表中的關鍵字(Primary Key)。屬性由型別(Type)和一個或多個值(Values)組成,相當於關係資料庫中的欄位(Field)由欄位名和資料型別組成,只是為了方便檢索的需要,LDAP中的Type可以有多個Value,而不是關係資料庫中為降低資料的冗餘性要求實現的各個域必須是不相關的。LDAP中條目的組織一般按照地理位置和組織關係進行組織,非常的直觀。LDAP把資料存放在檔案中,為提高效率可以使用基於索引的檔案資料庫,而不是關係資料庫。型別的一個例子就是mail,其值將是一個電子郵件地址。
LDAP的資訊是以樹型結構儲存的,在樹根一般定義國家(c=CN)或域名(dc=com),在其下則往往定義一個或多個組織 (organization)(o=Acme)或組織單元(organizational units) (ou=People)。一個組織單元可能包含諸如所有僱員、大樓內的所有印表機等資訊。此外,LDAP支援對條目能夠和必須支援哪些屬性進行控制,這是有一個特殊的稱為物件類別(objectClass)的屬性來實現的。該屬性的值決定了該條目必須遵循的一些規則,其規定了該條目能夠及至少應該包含哪些屬性。例如:inetorgPerson物件類需要支援sn(surname)和cn(common name)屬性,但也可以包含可選的如郵件,電話號碼等屬性。
LDAP簡稱對應
-
o:organization(組織-公司)
-
ou:organization unit(組織單元-部門)
-
c:countryName(國家)
-
dc:domainComponent(域名)
-
sn:surname(姓氏)
-
cn:common name(常用名稱)
二 實戰
1 新建pom
<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> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> <scope>provided</scope> </dependency> </dependencies>
2 實體類
package com.didispace;
import lombok.Data;
import org.springframework.ldap.odm.annotations.*;
import javax.naming.Name;
@Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson")
@Data
public class Person {
@Id
private Name id;
@DnAttribute(value = "uid", index = 3)
private String uid;
@Attribute(name = "cn")
private String commonName;
@Attribute(name = "sn")
private String suerName;
private String userPassword;
}
3 啟動類
package com.didispace;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4 Repository
package com.didispace;
import org.springframework.data.repository.CrudRepository;
import javax.naming.Name;
public interface PersonRepository extends CrudRepository<Person, Name> {
}
5 application.properties
spring.ldap.embedded.ldif=ldap-server.ldif
spring.ldap.embedded.base-dn=dc=didispace,dc=com
6 ldap-server.ldif
dn: dc=didispace,dc=com
objectClass: top
objectClass: domain
dn: ou=people,dc=didispace,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people
dn: uid=ben,ou=people,dc=didispace,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: didi
sn: zhaiyongchao
uid: didi
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
7 測試類
package com.didispace;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private PersonRepository personRepository;
@Test
public void findAll() throws Exception {
personRepository.findAll().forEach(p -> {
System.out.println(p);
});
}
@Test
public void save() throws Exception {
Person person = new Person();
person.setUid("uid:1");
person.setSuerName("AAA");
person.setCommonName("aaa");
person.setUserPassword("123456");
personRepository.save(person);
personRepository.findAll().forEach(p -> {
System.out.println(p);
});
}
}
三 測試結果
1 findAll測試結果
2018-11-02 21:53:12.896 WARN 24528 --- [ main] o.s.ldap.odm.core.impl.ObjectMetaData : The Entry class Person should be declared final
Person(id=uid=ben,ou=people,dc=didispace,dc=com, uid=ben, commonName=didi, suerName=zhaiyongchao, userPassword=123,83,72,65,125,110,70,67,101,98,87,106,120,102,97,76,98,72,72,71,49,81,107,53,85,85,52,116,114,98,118,81,61)
2 save測試結果
2018-11-02 21:51:10.727 WARN 21536 --- [ main] o.s.ldap.odm.core.impl.ObjectMetaData : The Entry class Person should be declared final
Person(id=uid=ben,ou=people,dc=didispace,dc=com, uid=ben, commonName=didi, suerName=zhaiyongchao, userPassword=123,83,72,65,125,110,70,67,101,98,87,106,120,102,97,76,98,72,72,71,49,81,107,53,85,85,52,116,114,98,118,81,61)
Person(id=uid=uid:1,ou=people,dc=didispace,dc=com, uid=uid:1, commonName=aaa, suerName=AAA, userPassword=49,50,51,52,53,54)
四 參考