@@ -62,6 +62,7 @@ | |||
<module>spring-boot-demo-tio</module> | |||
<module>spring-boot-demo-codegen</module> | |||
<module>spring-boot-demo-graylog</module> | |||
<module>spring-boot-demo-ldap</module> | |||
</modules> | |||
<packaging>pom</packaging> | |||
@@ -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 | |||
``` | |||
<?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> | |||
<artifactId>spring-boot-demo-ldap</artifactId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
<packaging>jar</packaging> | |||
<name>spring-boot-demo-ldap</name> | |||
<description>Demo project for Spring Boot</description> | |||
<parent> | |||
<artifactId>spring-boot-demo</artifactId> | |||
<groupId>com.xkcoding</groupId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
</parent> | |||
<properties> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-data-ldap</artifactId> | |||
</dependency> | |||
<!-- test --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<!-- lombok --> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> | |||
</project> | |||
``` | |||
## 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<Person, Name> { | |||
/** | |||
* 根据用户名查找 | |||
* | |||
* @param uid 用户名 | |||
* @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; | |||
/** | |||
* 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<Person> 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/ |
@@ -0,0 +1,49 @@ | |||
<?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> | |||
<artifactId>spring-boot-demo-ldap</artifactId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
<packaging>jar</packaging> | |||
<name>spring-boot-demo-ldap</name> | |||
<description>Demo project for Spring Boot</description> | |||
<parent> | |||
<artifactId>spring-boot-demo</artifactId> | |||
<groupId>com.xkcoding</groupId> | |||
<version>1.0.0-SNAPSHOT</version> | |||
</parent> | |||
<properties> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-data-ldap</artifactId> | |||
</dependency> | |||
<!-- test --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<!-- lombok --> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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<T> 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 <T> 泛型标记 | |||
* @return 响应信息 {@code Result} | |||
*/ | |||
public static <T> Result<T> success() { | |||
return new Result<>(ResultCode.SUCCESS); | |||
} | |||
/** | |||
* 返回成功-携带数据 | |||
* | |||
* @param data 响应数据 | |||
* @param <T> 泛型标记 | |||
* @return 响应信息 {@code Result} | |||
*/ | |||
public static <T> Result<T> success(@Nullable T data) { | |||
return new Result<>(ResultCode.SUCCESS, data); | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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<Person, Name> { | |||
/** | |||
* 根据用户名查找 | |||
* | |||
* @param uid 用户名 | |||
* @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); | |||
} |
@@ -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; | |||
} |
@@ -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); | |||
} |
@@ -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<Person> 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()); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
spring: | |||
ldap: | |||
urls: ldap://localhost:389 | |||
base: dc=example,dc=org | |||
username: cn=admin,dc=example,dc=org | |||
password: admin |
@@ -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); | |||
} | |||
} |