From 4870cd9e10063f322a7276e1a676b30fb883279e Mon Sep 17 00:00:00 2001 From: fxbin Date: Mon, 26 Aug 2019 02:43:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20springboot=20ldap=20demo?= =?UTF-8?q?=20=E7=A4=BA=E4=BE=8B=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + spring-boot-demo-ldap/README.md | 428 ++++++++++++++++++ spring-boot-demo-ldap/pom.xml | 49 ++ .../xkcoding/ldap/LdapDemoApplication.java | 19 + .../java/com/xkcoding/ldap/entity/Person.java | 95 ++++ .../java/com/xkcoding/ldap/entity/Result.java | 84 ++++ .../com/xkcoding/ldap/entity/ResultCode.java | 31 ++ .../ldap/exception/ServiceException.java | 48 ++ .../ldap/repository/PersonRepository.java | 49 ++ .../xkcoding/ldap/request/LoginRequest.java | 21 + .../xkcoding/ldap/service/PersonService.java | 41 ++ .../ldap/service/impl/PersonServiceImpl.java | 77 ++++ .../com/xkcoding/ldap/util/LdapUtils.java | 77 ++++ .../src/main/resources/application.yml | 6 + .../ldap/LdapDemoApplicationTests.java | 77 ++++ 15 files changed, 1103 insertions(+) create mode 100644 spring-boot-demo-ldap/README.md create mode 100644 spring-boot-demo-ldap/pom.xml create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/LdapDemoApplication.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Person.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Result.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/ResultCode.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/request/LoginRequest.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java create mode 100644 spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java create mode 100644 spring-boot-demo-ldap/src/main/resources/application.yml create mode 100644 spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java diff --git a/pom.xml b/pom.xml index 5455297..1ee5d37 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,7 @@ spring-boot-demo-tio spring-boot-demo-codegen spring-boot-demo-graylog + spring-boot-demo-ldap pom diff --git a/spring-boot-demo-ldap/README.md b/spring-boot-demo-ldap/README.md new file mode 100644 index 0000000..95b91c4 --- /dev/null +++ b/spring-boot-demo-ldap/README.md @@ -0,0 +1,428 @@ +# spring-boot-demo-ldap + +> 此 demo 主要演示了 Spring Boot 如何集成 `spring-boot-starter-data-ldap` 完成对 Ldap 的基本CURD操作, 并给出以登录为实战的api 示例 + +## docker openldap 安装步骤 + +> 参考: https://github.com/osixia/docker-openldap +1. 下载镜像: `docker pull osixia/openldap:1.2.5` + +2. 运行容器: `docker run -p 389:389 -p 636:636 --name my-openldap --detach osixia/openldap:1.2.5` + +3. 添加管理员: `docker exec my-openldap ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin` + +4. 停止容器:`docker stop my-openldap` + +5. 启动容器:`docker start my-openldap` + + +## pom.xml + +``` + + + 4.0.0 + + spring-boot-demo-ldap + 1.0.0-SNAPSHOT + jar + + spring-boot-demo-ldap + Demo project for Spring Boot + + + spring-boot-demo + com.xkcoding + 1.0.0-SNAPSHOT + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-data-ldap + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.projectlombok + lombok + true + provided + + + + + +``` + +## 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; + +/** + * People + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 0:51 + */ +@Data +@Entry( + base = "ou=people", + objectClasses = {"posixAccount", "inetOrgPerson", "top"} +) +public class Person implements Serializable { + + private static final long serialVersionUID = -7946768337975852352L; + + @Id + private Name id; + + private String uidNumber; + + private String gidNumber; + + /** + * 用户名 + */ + @DnAttribute(value = "uid", index = 1) + private String uid; + + /** + * 姓名 + */ + @Attribute(name = "cn") + private String personName; + + /** + * 密码 + */ + private String userPassword; + + /** + * 名字 + */ + private String givenName; + + /** + * 姓氏 + */ + @Attribute(name = "sn") + private String surname; + + /** + * 邮箱 + */ + private String mail; + + /** + * 职位 + */ + private String title; + + /** + * 根目录 + */ + private String homeDirectory; + + /** + * loginShell + */ + 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; + +/** + * PersonRepository + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:02 + */ +@Repository +public interface PersonRepository extends CrudRepository { + + /** + * 根据用户名查找 + * + * @param uid 用户名 + * @return com.xkcoding.ldap.entity.Person + */ + Person findByUid(String uid); + + /** + * 查询全部 + * @return + */ + @Override + Iterable findAll(); + + /** + * 保存 + * @param s + * @param + * @return + */ + @Override + 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; + +/** + * PersonService + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:05 + */ +public interface PersonService { + + /** + * 登录 + * @param request com.xkcoding.ldap.request.LoginRequest + * @return com.xkcoding.ldap.entity.Result + */ + Result login(LoginRequest request); + + /** + * 查询全部 + * @return com.xkcoding.ldap.entity.Result + */ + Result listAllPerson(); + + /** + * 保存 + * @param person com.xkcoding.ldap.entity.Person + */ + void save(Person person); + + /** + * 删除 + * @param person com.xkcoding.ldap.entity.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; + +/** + * PersonServiceImpl + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:05 + */ +@Slf4j +@Service +public class PersonServiceImpl implements PersonService { + + @Resource + private PersonRepository personRepository; + + @Override + public Result login(LoginRequest request) { + + log.info("IN LDAP auth"); + + Person user = personRepository.findByUid(request.getUsername()); + + try { + if(ObjectUtils.isEmpty(user)) { + throw new ServiceException("用户名或密码错误,请重新尝试"); + } else { + user.setUserPassword(LdapUtils.asciiToString(user.getUserPassword())); + if (!LdapUtils.verify(user.getUserPassword(), request.getPassword())) { + throw new ServiceException("用户名或密码错误,请重新尝试"); + } + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + log.info("user info:{}", user); + return Result.success(user); + } + + @Override + public Result listAllPerson() { + Iterable personList = personRepository.findAll(); + personList.forEach(person -> { + person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword())); + }); + return Result.success(personList); + } + + @Override + public void save(Person person) { + Person p = personRepository.save(person); + log.info("用户{}保存成功", p.getUid()); + } + + @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; + +/** + * LdapDemoApplicationTest + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:06 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class LdapDemoApplicationTests { + + @Resource + private PersonService personService; + + @Test + public void contextLoads() { + } + + @Test + public void loginTest() { + LoginRequest loginRequest = LoginRequest.builder().username("wangwu").password("123456").build(); + Result login = personService.login(loginRequest); + System.out.println(login); + } + + @Test + public void listAllPersonTest() { + Result result = personService.listAllPerson(); + System.out.println(result); + } + + @Test + public void saveTest() { + Person person = new Person(); + + person.setUid("zhaosi"); + + person.setSurname("赵"); + person.setGivenName("四"); + person.setUserPassword("123456"); + + // required field + person.setPersonName("赵四"); + person.setUidNumber("666"); + person.setGidNumber("666"); + person.setHomeDirectory("/home/zhaosi"); + person.setLoginShell("/bin/bash"); + + personService.save(person); + } + + + @Test + public void deleteTest() { + Person person = new Person(); + person.setUid("zhaosi"); + + personService.delete(person); + } +} +``` + +## 参考 +spring-data-ldap 官方文档: https://docs.spring.io/spring-data/ldap/docs/2.1.10.RELEASE/reference/html/ diff --git a/spring-boot-demo-ldap/pom.xml b/spring-boot-demo-ldap/pom.xml new file mode 100644 index 0000000..f5be7fa --- /dev/null +++ b/spring-boot-demo-ldap/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + spring-boot-demo-ldap + 1.0.0-SNAPSHOT + jar + + spring-boot-demo-ldap + Demo project for Spring Boot + + + spring-boot-demo + com.xkcoding + 1.0.0-SNAPSHOT + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-data-ldap + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.projectlombok + lombok + true + provided + + + + diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/LdapDemoApplication.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/LdapDemoApplication.java new file mode 100644 index 0000000..f463f85 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/LdapDemoApplication.java @@ -0,0 +1,19 @@ +package com.xkcoding.ldap; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * LdapDemoApplication Ldap demo 启动类 + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 0:37 + */ +@SpringBootApplication +public class LdapDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(LdapDemoApplication.class, args); + } +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Person.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Person.java new file mode 100644 index 0000000..38029b2 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Person.java @@ -0,0 +1,95 @@ +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; + +/** + * People + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 0:51 + */ +@Data +@Entry( + base = "ou=people", + objectClasses = {"posixAccount", "inetOrgPerson", "top"} +) +public class Person implements Serializable { + + private static final long serialVersionUID = -7946768337975852352L; + + @Id + private Name id; + + /** + * 用户id + */ + private String uidNumber; + + /** + * 用户名 + */ + @DnAttribute(value = "uid", index = 1) + private String uid; + + /** + * 姓名 + */ + @Attribute(name = "cn") + private String personName; + + /** + * 密码 + */ + private String userPassword; + + /** + * 名字 + */ + private String givenName; + + /** + * 姓氏 + */ + @Attribute(name = "sn") + private String surname; + + /** + * 邮箱 + */ + private String mail; + + /** + * 职位 + */ + private String title; + + /** + * 部门 + */ + private String departmentNumber; + + /** + * 部门id + */ + private String gidNumber; + + /** + * 根目录 + */ + private String homeDirectory; + + /** + * loginShell + */ + private String loginShell; + + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Result.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Result.java new file mode 100644 index 0000000..00c203e --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/Result.java @@ -0,0 +1,84 @@ +package com.xkcoding.ldap.entity; + +import lombok.Data; +import org.springframework.lang.Nullable; + +import java.io.Serializable; + +/** + * Result + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:44 + */ +@Data +public class Result implements Serializable { + + private static final long serialVersionUID = 1696194043024336235L; + + /** + * 错误码 + */ + private int errcode; + + /** + * 错误信息 + */ + private String errmsg; + + /** + * 响应数据 + */ + private T data; + + public Result() { + } + + private Result(ResultCode resultCode) { + this(resultCode.code, resultCode.msg); + } + + private Result(ResultCode resultCode, T data) { + this(resultCode.code, resultCode.msg, data); + } + + private Result(int errcode, String errmsg) { + this(errcode, errmsg, null); + } + + private Result(int errcode, String errmsg, T data) { + this.errcode = errcode; + this.errmsg = errmsg; + this.data = data; + } + + + + /** + * 返回成功 + * + * @param 泛型标记 + * @return 响应信息 {@code Result} + */ + public static Result success() { + return new Result<>(ResultCode.SUCCESS); + } + + + /** + * 返回成功-携带数据 + * + * @param data 响应数据 + * @param 泛型标记 + * @return 响应信息 {@code Result} + */ + public static Result success(@Nullable T data) { + return new Result<>(ResultCode.SUCCESS, data); + } + + + + + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/ResultCode.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/ResultCode.java new file mode 100644 index 0000000..4072345 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/entity/ResultCode.java @@ -0,0 +1,31 @@ +package com.xkcoding.ldap.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * ResultCode + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:47 + */ +@Getter +@AllArgsConstructor +public enum ResultCode { + + /** + * 接口调用成功 + */ + SUCCESS(0, "Request Successful"), + + /** + * 服务器暂不可用,建议稍候重试。建议重试次数不超过3次。 + */ + FAILURE(-1, "System Busy"); + + final int code; + + final String msg; + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java new file mode 100644 index 0000000..581c53c --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/exception/ServiceException.java @@ -0,0 +1,48 @@ +package com.xkcoding.ldap.exception; + +import com.xkcoding.ldap.entity.ResultCode; +import lombok.Getter; + +/** + * ServiceException + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:53 + */ +public class ServiceException extends RuntimeException { + + @Getter + private int errcode; + + @SuppressWarnings("NullableProblems") + @Getter + private String errmsg; + + public ServiceException(ResultCode resultCode) { + this(resultCode.getCode(), resultCode.getMsg()); + } + + public ServiceException(String message) { + super(message); + } + + public ServiceException(Integer errcode, String errmsg) { + super(errmsg); + this.errcode = errcode; + this.errmsg = errmsg; + } + + public ServiceException(String message, Throwable cause) { + super(message, cause); + } + + public ServiceException(Throwable cause) { + super(cause); + } + + public ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java new file mode 100644 index 0000000..8703b17 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/repository/PersonRepository.java @@ -0,0 +1,49 @@ +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; + +/** + * PersonRepository + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:02 + */ +@Repository +public interface PersonRepository extends CrudRepository { + + /** + * 根据用户名查找 + * + * @param uid 用户名 + * @return com.xkcoding.ldap.entity.Person + */ + Person findByUid(String uid); + + /** + * 查询全部 + * @return + */ + @Override + Iterable findAll(); + + /** + * 保存 + * @param s + * @param + * @return + */ + @Override + S save(S s); + + /** + * 删除 + * @param person + */ + @Override + void delete(Person person); +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/request/LoginRequest.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/request/LoginRequest.java new file mode 100644 index 0000000..c1d2380 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/request/LoginRequest.java @@ -0,0 +1,21 @@ +package com.xkcoding.ldap.request; + +import lombok.Builder; +import lombok.Data; + +/** + * LoginRequest + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:50 + */ +@Data +@Builder +public class LoginRequest { + + private String username; + + private String password; + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java new file mode 100644 index 0000000..6b31851 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/PersonService.java @@ -0,0 +1,41 @@ +package com.xkcoding.ldap.service; + +import com.xkcoding.ldap.entity.Person; +import com.xkcoding.ldap.entity.Result; +import com.xkcoding.ldap.request.LoginRequest; + +/** + * PersonService + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:05 + */ +public interface PersonService { + + /** + * 登录 + * @param request com.xkcoding.ldap.request.LoginRequest + * @return com.xkcoding.ldap.entity.Result + */ + Result login(LoginRequest request); + + /** + * 查询全部 + * @return com.xkcoding.ldap.entity.Result + */ + Result listAllPerson(); + + /** + * 保存 + * @param person com.xkcoding.ldap.entity.Person + */ + void save(Person person); + + /** + * 删除 + * @param person com.xkcoding.ldap.entity.Person + */ + void delete(Person person); + +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java new file mode 100644 index 0000000..5687f44 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java @@ -0,0 +1,77 @@ +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; + +/** + * PersonServiceImpl + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:05 + */ +@Slf4j +@Service +public class PersonServiceImpl implements PersonService { + + @Resource + private PersonRepository personRepository; + + @Override + public Result login(LoginRequest request) { + + log.info("IN LDAP auth"); + + Person user = personRepository.findByUid(request.getUsername()); + + try { + if(ObjectUtils.isEmpty(user)) { + throw new ServiceException("用户名或密码错误,请重新尝试"); + } else { + user.setUserPassword(LdapUtils.asciiToString(user.getUserPassword())); + if (!LdapUtils.verify(user.getUserPassword(), request.getPassword())) { + throw new ServiceException("用户名或密码错误,请重新尝试"); + } + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + log.info("user info:{}", user); + return Result.success(user); + } + + @Override + public Result listAllPerson() { + Iterable personList = personRepository.findAll(); + personList.forEach(person -> { + person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword())); + }); + return Result.success(personList); + } + + @Override + public void save(Person person) { + Person p = personRepository.save(person); + log.info("用户{}保存成功", p.getUid()); + } + + @Override + public void delete(Person person) { + personRepository.delete(person); + log.info("删除用户{}成功", person.getUid()); + } +} diff --git a/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java new file mode 100644 index 0000000..645ec71 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/java/com/xkcoding/ldap/util/LdapUtils.java @@ -0,0 +1,77 @@ +package com.xkcoding.ldap.util; + +import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * LdapUtils + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:03 + */ +public class LdapUtils { + + /** + * 校验密码 + * @param ldappw ldap 加密密码 + * @param inputpw 用户输入 + * @return boolean + * @throws NoSuchAlgorithmException + */ + public static boolean verify(String ldappw, String inputpw) + 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); + } + // 解码BASE64 + byte[] ldappwbyte = Base64.decode(ldappw); + byte[] shacode; + byte[] salt; + + // 前20位是SHA-1加密段,20位后是最初加密时的随机明文 + if (ldappwbyte.length <= 20) { + shacode = ldappwbyte; + 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); + } + // 把用户输入的密码添加到摘要计算信息 + md.update(inputpw.getBytes()); + // 把随机明文添加到摘要计算信息 + md.update(salt); + + // 按SSHA把当前用户密码进行计算 + byte[] inputpwbyte = md.digest(); + + // 返回校验结果 + return MessageDigest.isEqual(shacode, inputpwbyte); + } + + /** + * Ascii转换为字符串 + * @param value + * @return + */ + public static String asciiToString(String value) { + StringBuilder sbu = new StringBuilder(); + String[] chars = value.split(","); + for (String aChar : chars) { + sbu.append((char) Integer.parseInt(aChar)); + } + return sbu.toString(); + } + +} diff --git a/spring-boot-demo-ldap/src/main/resources/application.yml b/spring-boot-demo-ldap/src/main/resources/application.yml new file mode 100644 index 0000000..06c2c28 --- /dev/null +++ b/spring-boot-demo-ldap/src/main/resources/application.yml @@ -0,0 +1,6 @@ +spring: + ldap: + urls: ldap://localhost:389 + base: dc=example,dc=org + username: cn=admin,dc=example,dc=org + password: admin diff --git a/spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java b/spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java new file mode 100644 index 0000000..b951777 --- /dev/null +++ b/spring-boot-demo-ldap/src/test/java/com/xkcoding/ldap/LdapDemoApplicationTests.java @@ -0,0 +1,77 @@ +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; + +/** + * LdapDemoApplicationTest + * + * @author fxbin + * @version v1.0 + * @since 2019/8/26 1:06 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class LdapDemoApplicationTests { + + @Resource + private PersonService personService; + + @Test + public void contextLoads() { + } + + @Test + public void loginTest() { + LoginRequest loginRequest = LoginRequest.builder().username("wangwu").password("123456").build(); + Result login = personService.login(loginRequest); + System.out.println(login); + } + + @Test + public void listAllPersonTest() { + Result result = personService.listAllPerson(); + System.out.println(result); + } + + @Test + public void saveTest() { + Person person = new Person(); + + person.setUid("zhaosi"); + + person.setSurname("赵"); + person.setGivenName("四"); + person.setUserPassword("123456"); + + // required field + person.setPersonName("赵四"); + person.setUidNumber("666"); + person.setGidNumber("666"); + person.setHomeDirectory("/home/zhaosi"); + person.setLoginShell("/bin/bash"); + + personService.save(person); + } + + + @Test + public void deleteTest() { + Person person = new Person(); + person.setUid("zhaosi"); + + personService.delete(person); + } + + + + +}