Browse Source

spring-boot-demo-ldap 完成

pull/1/head
Yangkai.Shen 5 years ago
parent
commit
c1a74536a2
9 changed files with 147 additions and 176 deletions
  1. +69
    -104
      spring-boot-demo-ldap/README.md
  2. +1
    -1
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/api/Result.java
  3. +1
    -1
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/api/ResultCode.java
  4. +1
    -2
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java
  5. +0
    -23
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java
  6. +10
    -6
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java
  7. +29
    -12
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java
  8. +23
    -22
      spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java
  9. +13
    -5
      spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java

+ 69
- 104
spring-boot-demo-ldap/README.md View File

@@ -1,6 +1,6 @@
# spring-boot-demo-ldap

> 此 demo 主要演示了 Spring Boot 如何集成 `spring-boot-starter-data-ldap` 完成对 Ldap 的基本CURD操作, 并给出以登录为实战的api 示例
> 此 demo 主要演示了 Spring Boot 如何集成 `spring-boot-starter-data-ldap` 完成对 Ldap 的基本 CURD操作, 并给出以登录为实战的 API 示例

## docker openldap 安装步骤

@@ -18,7 +18,7 @@

## pom.xml

```
```xml
<?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"
@@ -68,25 +68,24 @@
</dependencies>

</project>
```

## application.yml

```yaml
spring:
ldap:
urls: ldap://localhost:389
base: dc=example,dc=org
username: cn=admin,dc=example,dc=org
password: admin
```

## Person.java

> 实体类
> @Entry 注解 映射ldap对象关系
```
package com.xkcoding.ldap.entity;

import lombok.Data;
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 javax.naming.Name;
import java.io.Serializable;

```java
/**
* People
*
@@ -158,20 +157,11 @@ public class Person implements Serializable {
*/
private String loginShell;
}

```

## PersonRepository.java
> person 数据持久层
```
package com.xkcoding.ldap.repository;

import com.xkcoding.ldap.entity.Person;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import javax.naming.Name;

```java
/**
* PersonRepository
*
@@ -189,42 +179,12 @@ public interface PersonRepository extends CrudRepository<Person, Name> {
* @return com.xkcoding.ldap.entity.Person
*/
Person findByUid(String uid);

/**
* 查询全部
* @return
*/
@Override
Iterable<Person> findAll();

/**
* 保存
* @param s
* @param <S>
* @return
*/
@Override
<S extends Person> S save(S s);

/**
* 删除
* @param person
*/
@Override
void delete(Person person);
}

```

## PersonService.java
> 数据操作服务
```
package com.xkcoding.ldap.service;

import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.request.LoginRequest;

```java
/**
* PersonService
*
@@ -236,54 +196,40 @@ public interface PersonService {

/**
* 登录
* @param request com.xkcoding.ldap.request.LoginRequest
* @return com.xkcoding.ldap.entity.Result
*
* @param request {@link LoginRequest}
* @return {@link Result}
*/
Result login(LoginRequest request);

/**
* 查询全部
* @return com.xkcoding.ldap.entity.Result
*
* @return {@link Result}
*/
Result listAllPerson();

/**
* 保存
* @param person com.xkcoding.ldap.entity.Person
*
* @param person {@link Person}
*/
void save(Person person);

/**
* 删除
* @param person com.xkcoding.ldap.entity.Person
*
* @param person {@link Person}
*/
void delete(Person person);
}

}
```

## PersonServiceImpl.java
> person数据操作服务具体逻辑实现类

```
package com.xkcoding.ldap.service.impl;

import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.exception.ServiceException;
import com.xkcoding.ldap.repository.PersonRepository;
import com.xkcoding.ldap.request.LoginRequest;
import com.xkcoding.ldap.service.PersonService;
import com.xkcoding.ldap.util.LdapUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.List;

```java
/**
* PersonServiceImpl
*
@@ -293,20 +239,24 @@ import java.util.List;
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class PersonServiceImpl implements PersonService {
private final PersonRepository personRepository;

@Resource
private PersonRepository personRepository;

/**
* 登录
*
* @param request {@link LoginRequest}
* @return {@link Result}
*/
@Override
public Result login(LoginRequest request) {

log.info("IN LDAP auth");

Person user = personRepository.findByUid(request.getUsername());

try {
if(ObjectUtils.isEmpty(user)) {
if (ObjectUtils.isEmpty(user)) {
throw new ServiceException("用户名或密码错误,请重新尝试");
} else {
user.setUserPassword(LdapUtils.asciiToString(user.getUserPassword()));
@@ -322,46 +272,46 @@ public class PersonServiceImpl implements PersonService {
return Result.success(user);
}

/**
* 查询全部
*
* @return {@link Result}
*/
@Override
public Result listAllPerson() {
Iterable<Person> personList = personRepository.findAll();
personList.forEach(person -> {
person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword()));
});
personList.forEach(person -> person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword())));
return Result.success(personList);
}

/**
* 保存
*
* @param person {@link Person}
*/
@Override
public void save(Person person) {
Person p = personRepository.save(person);
log.info("用户{}保存成功", p.getUid());
}

/**
* 删除
*
* @param person {@link Person}
*/
@Override
public void delete(Person person) {
personRepository.delete(person);
log.info("删除用户{}成功", person.getUid());
}
}

```

## LdapDemoApplicationTests.java
> 测试
```
package com.xkcoding.ldap;

import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.request.LoginRequest;
import com.xkcoding.ldap.service.PersonService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

```java
/**
* LdapDemoApplicationTest
*
@@ -380,6 +330,9 @@ public class LdapDemoApplicationTests {
public void contextLoads() {
}

/**
* 测试查询单个
*/
@Test
public void loginTest() {
LoginRequest loginRequest = LoginRequest.builder().username("wangwu").password("123456").build();
@@ -387,12 +340,18 @@ public class LdapDemoApplicationTests {
System.out.println(login);
}

/**
* 测试查询列表
*/
@Test
public void listAllPersonTest() {
Result result = personService.listAllPerson();
System.out.println(result);
}

/**
* 测试保存
*/
@Test
public void saveTest() {
Person person = new Person();
@@ -413,7 +372,9 @@ public class LdapDemoApplicationTests {
personService.save(person);
}


/**
* 测试删除
*/
@Test
public void deleteTest() {
Person person = new Person();
@@ -421,8 +382,12 @@ public class LdapDemoApplicationTests {

personService.delete(person);
}

}
```

## 其余代码参见本 demo

## 参考

spring-data-ldap 官方文档: https://docs.spring.io/spring-data/ldap/docs/2.1.10.RELEASE/reference/html/

spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Result.java → spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/api/Result.java View File

@@ -1,4 +1,4 @@
package com.xkcoding.ldap.entity;
package com.xkcoding.ldap.api;

import lombok.Data;
import org.springframework.lang.Nullable;

spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/ResultCode.java → spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/api/ResultCode.java View File

@@ -1,4 +1,4 @@
package com.xkcoding.ldap.entity;
package com.xkcoding.ldap.api;

import lombok.AllArgsConstructor;
import lombok.Getter;

+ 1
- 2
spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java View File

@@ -1,6 +1,6 @@
package com.xkcoding.ldap.exception;

import com.xkcoding.ldap.entity.ResultCode;
import com.xkcoding.ldap.api.ResultCode;
import lombok.Getter;

/**
@@ -15,7 +15,6 @@ public class ServiceException extends RuntimeException {
@Getter
private int errcode;

@SuppressWarnings("NullableProblems")
@Getter
private String errmsg;



+ 0
- 23
spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java View File

@@ -23,27 +23,4 @@ public interface PersonRepository extends CrudRepository<Person, Name> {
* @return com.xkcoding.ldap.entity.Person
*/
Person findByUid(String uid);

/**
* 查询全部
* @return
*/
@Override
Iterable<Person> findAll();

/**
* 保存
* @param s
* @param <S>
* @return
*/
@Override
<S extends Person> S save(S s);

/**
* 删除
* @param person
*/
@Override
void delete(Person person);
}

+ 10
- 6
spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java View File

@@ -1,7 +1,7 @@
package com.xkcoding.ldap.service;

import com.xkcoding.ldap.api.Result;
import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.request.LoginRequest;

/**
@@ -15,26 +15,30 @@ public interface PersonService {

/**
* 登录
* @param request com.xkcoding.ldap.request.LoginRequest
* @return com.xkcoding.ldap.entity.Result
*
* @param request {@link LoginRequest}
* @return {@link Result}
*/
Result login(LoginRequest request);

/**
* 查询全部
* @return com.xkcoding.ldap.entity.Result
*
* @return {@link Result}
*/
Result listAllPerson();

/**
* 保存
* @param person com.xkcoding.ldap.entity.Person
*
* @param person {@link Person}
*/
void save(Person person);

/**
* 删除
* @param person com.xkcoding.ldap.entity.Person
*
* @param person {@link Person}
*/
void delete(Person person);



+ 29
- 12
spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java View File

@@ -1,20 +1,19 @@
package com.xkcoding.ldap.service.impl;

import com.xkcoding.ldap.api.Result;
import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.exception.ServiceException;
import com.xkcoding.ldap.repository.PersonRepository;
import com.xkcoding.ldap.request.LoginRequest;
import com.xkcoding.ldap.service.PersonService;
import com.xkcoding.ldap.util.LdapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
* PersonServiceImpl
@@ -25,20 +24,24 @@ import java.util.List;
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class PersonServiceImpl implements PersonService {
private final PersonRepository personRepository;

@Resource
private PersonRepository personRepository;

/**
* 登录
*
* @param request {@link LoginRequest}
* @return {@link Result}
*/
@Override
public Result login(LoginRequest request) {

log.info("IN LDAP auth");

Person user = personRepository.findByUid(request.getUsername());

try {
if(ObjectUtils.isEmpty(user)) {
if (ObjectUtils.isEmpty(user)) {
throw new ServiceException("用户名或密码错误,请重新尝试");
} else {
user.setUserPassword(LdapUtils.asciiToString(user.getUserPassword()));
@@ -54,24 +57,38 @@ public class PersonServiceImpl implements PersonService {
return Result.success(user);
}

/**
* 查询全部
*
* @return {@link Result}
*/
@Override
public Result listAllPerson() {
Iterable<Person> personList = personRepository.findAll();
personList.forEach(person -> {
person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword()));
});
personList.forEach(person -> person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword())));
return Result.success(personList);
}

/**
* 保存
*
* @param person {@link Person}
*/
@Override
public void save(Person person) {
Person p = personRepository.save(person);
log.info("用户{}保存成功", p.getUid());
}

/**
* 删除
*
* @param person {@link Person}
*/
@Override
public void delete(Person person) {
personRepository.delete(person);
log.info("删除用户{}成功", person.getUid());
}

}

+ 23
- 22
spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java View File

@@ -16,54 +16,55 @@ public class LdapUtils {

/**
* 校验密码
* @param ldappw ldap 加密密码
* @param inputpw 用户输入
*
* @param ldapPassword ldap 加密密码
* @param inputPassword 用户输入
* @return boolean
* @throws NoSuchAlgorithmException
* @throws NoSuchAlgorithmException 加解密异常
*/
public static boolean verify(String ldappw, String inputpw)
throws NoSuchAlgorithmException {
public static boolean verify(String ldapPassword, String inputPassword) throws NoSuchAlgorithmException {

// MessageDigest 提供了消息摘要算法,如 MD5 或 SHA,的功能,这里LDAP使用的是SHA-1
MessageDigest md = MessageDigest.getInstance("SHA-1");

// 取出加密字符
if (ldappw.startsWith("{SSHA}")) {
ldappw = ldappw.substring(6);
} else if (ldappw.startsWith("{SHA}")) {
ldappw = ldappw.substring(5);
if (ldapPassword.startsWith("{SSHA}")) {
ldapPassword = ldapPassword.substring(6);
} else if (ldapPassword.startsWith("{SHA}")) {
ldapPassword = ldapPassword.substring(5);
}
// 解码BASE64
byte[] ldappwbyte = Base64.decode(ldappw);
byte[] shacode;
byte[] ldapPasswordByte = Base64.decode(ldapPassword);
byte[] shaCode;
byte[] salt;

// 前20位是SHA-1加密段,20位后是最初加密时的随机明文
if (ldappwbyte.length <= 20) {
shacode = ldappwbyte;
if (ldapPasswordByte.length <= 20) {
shaCode = ldapPasswordByte;
salt = new byte[0];
} else {
shacode = new byte[20];
salt = new byte[ldappwbyte.length - 20];
System.arraycopy(ldappwbyte, 0, shacode, 0, 20);
System.arraycopy(ldappwbyte, 20, salt, 0, salt.length);
shaCode = new byte[20];
salt = new byte[ldapPasswordByte.length - 20];
System.arraycopy(ldapPasswordByte, 0, shaCode, 0, 20);
System.arraycopy(ldapPasswordByte, 20, salt, 0, salt.length);
}
// 把用户输入的密码添加到摘要计算信息
md.update(inputpw.getBytes());
md.update(inputPassword.getBytes());
// 把随机明文添加到摘要计算信息
md.update(salt);

// 按SSHA把当前用户密码进行计算
byte[] inputpwbyte = md.digest();
byte[] inputPasswordByte = md.digest();

// 返回校验结果
return MessageDigest.isEqual(shacode, inputpwbyte);
return MessageDigest.isEqual(shaCode, inputPasswordByte);
}

/**
* Ascii转换为字符串
* @param value
* @return
*
* @param value Ascii串
* @return 字符串
*/
public static String asciiToString(String value) {
StringBuilder sbu = new StringBuilder();


+ 13
- 5
spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java View File

@@ -1,7 +1,7 @@
package com.xkcoding.ldap;

import com.xkcoding.ldap.api.Result;
import com.xkcoding.ldap.entity.Person;
import com.xkcoding.ldap.entity.Result;
import com.xkcoding.ldap.request.LoginRequest;
import com.xkcoding.ldap.service.PersonService;
import org.junit.Test;
@@ -29,6 +29,9 @@ public class LdapDemoApplicationTests {
public void contextLoads() {
}

/**
* 测试查询单个
*/
@Test
public void loginTest() {
LoginRequest loginRequest = LoginRequest.builder().username("wangwu").password("123456").build();
@@ -36,12 +39,18 @@ public class LdapDemoApplicationTests {
System.out.println(login);
}

/**
* 测试查询列表
*/
@Test
public void listAllPersonTest() {
Result result = personService.listAllPerson();
System.out.println(result);
}

/**
* 测试保存
*/
@Test
public void saveTest() {
Person person = new Person();
@@ -62,7 +71,9 @@ public class LdapDemoApplicationTests {
personService.save(person);
}


/**
* 测试删除
*/
@Test
public void deleteTest() {
Person person = new Person();
@@ -71,7 +82,4 @@ public class LdapDemoApplicationTests {
personService.delete(person);
}




}

Loading…
Cancel
Save