diff --git a/spring-ldap/pom.xml b/spring-ldap/pom.xml
index 16d4879f10..f000b07a09 100644
--- a/spring-ldap/pom.xml
+++ b/spring-ldap/pom.xml
@@ -1,131 +1,143 @@
- 4.0.0
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
- com.baeldung
- spring-ldap
- 0.1-SNAPSHOT
- jar
+ com.baeldung
+ spring-ldap
+ 0.1-SNAPSHOT
+ jar
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
-
- 2.3.1.RELEASE
- 4.3.6.RELEASE
- 1.5.5
- 0.9.15
-
+
+ 2.3.1.RELEASE
+ 4.3.6.RELEASE
+ 1.5.5
+ 0.9.15
+
-
- spring-ldap
-
+
+ spring-ldap
+
-
+
-
- org.springframework.ldap
- spring-ldap-core
- ${spring-ldap.version}
-
-
- commons-logging
- commons-logging
-
-
-
+
+ org.springframework.ldap
+ spring-ldap-core
+ ${spring-ldap.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
-
- org.springframework
- spring-context
- ${spring-context.version}
-
+
+ org.springframework
+ spring-context
+ ${spring-context.version}
+
-
-
- org.springframework.ldap
- spring-ldap-test
- ${spring-ldap.version}
- test
-
-
- commons-logging
- commons-logging
-
-
-
+
+
+ org.springframework.ldap
+ spring-ldap-test
+ ${spring-ldap.version}
+ test
+
+
+ commons-logging
+ commons-logging
+
+
+
-
-
- org.apache.directory.server
- apacheds-core
- ${apacheds.version}
- test
-
-
- org.apache.directory.server
- apacheds-core-entry
- ${apacheds.version}
- test
-
-
- org.apache.directory.server
- apacheds-protocol-shared
- ${apacheds.version}
- test
-
-
- org.apache.directory.server
- apacheds-protocol-ldap
- ${apacheds.version}
- test
-
-
- org.apache.directory.server
- apacheds-server-jndi
- ${apacheds.version}
- test
-
-
- org.apache.directory.shared
- shared-ldap
- ${shared-ldap.version}
- test
-
+
+
+ org.apache.directory.server
+ apacheds-core
+ ${apacheds.version}
+ test
+
+
+ org.apache.directory.server
+ apacheds-core-entry
+ ${apacheds.version}
+ test
+
+
+ org.apache.directory.server
+ apacheds-protocol-shared
+ ${apacheds.version}
+ test
+
+
+ org.apache.directory.server
+ apacheds-protocol-ldap
+ ${apacheds.version}
+ test
+
+
+ org.apache.directory.server
+ apacheds-server-jndi
+ ${apacheds.version}
+ test
+
+
+ org.apache.directory.shared
+ shared-ldap
+ ${shared-ldap.version}
+ test
+
-
-
-
- live
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- integration-test
-
- test
-
-
-
- **/*IntegrationTest.java
-
-
- **/*LiveTest.java
-
-
-
-
-
-
-
-
-
+
+
+ org.springframework.data
+ spring-data-ldap
+ 1.0.6.RELEASE
+
+
+ org.springframework.data
+ spring-data-jpa
+ 1.11.6.RELEASE
+
+
+
+
+
+ live
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*IntegrationTest.java
+
+
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java
new file mode 100644
index 0000000000..726fa53b02
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java
@@ -0,0 +1,55 @@
+package com.baeldung.ldap.data.repository;
+
+import javax.naming.Name;
+
+import org.springframework.ldap.odm.annotations.Attribute;
+import org.springframework.ldap.odm.annotations.Entry;
+import org.springframework.ldap.odm.annotations.Id;
+
+@Entry(base = "ou=users", objectClasses = { "person", "inetOrgPerson", "top" })
+public class User {
+
+ @Id
+ private Name id;
+
+ private @Attribute(name = "cn") String username;
+ private @Attribute(name = "sn") String password;
+
+ public User() {
+ }
+
+ public User(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public Name getId() {
+ return id;
+ }
+
+ public void setId(Name id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return username;
+ }
+
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java
new file mode 100644
index 0000000000..9140616eee
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java
@@ -0,0 +1,17 @@
+package com.baeldung.ldap.data.repository;
+
+import java.util.List;
+
+import org.springframework.data.ldap.repository.LdapRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserRepository extends LdapRepository {
+
+ public User findByUsername(String username);
+
+ public User findByUsernameAndPassword(String username, String password);
+
+ public List findByUsernameLikeIgnoreCase(String username);
+
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java
new file mode 100644
index 0000000000..753c5f6c34
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java
@@ -0,0 +1,83 @@
+package com.baeldung.ldap.data.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.ldap.core.*;
+import org.springframework.ldap.support.LdapNameBuilder;
+
+import javax.naming.Name;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.List;
+
+public class LdapClient {
+
+ @Autowired
+ private Environment env;
+
+ @Autowired
+ private ContextSource contextSource;
+
+ @Autowired
+ private LdapTemplate ldapTemplate;
+
+ public void authenticate(final String username, final String password) {
+ contextSource.getContext("cn=" + username + ",ou=users," + env.getRequiredProperty("ldap.partitionSuffix"), password);
+ }
+
+ public List search(final String username) {
+ return ldapTemplate.search(
+ "ou=users",
+ "cn=" + username,
+ (AttributesMapper) attrs -> (String) attrs
+ .get("cn")
+ .get());
+ }
+
+ public void create(final String username, final String password) {
+ Name dn = LdapNameBuilder
+ .newInstance()
+ .add("ou", "users")
+ .add("cn", username)
+ .build();
+ DirContextAdapter context = new DirContextAdapter(dn);
+
+ context.setAttributeValues("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" });
+ context.setAttributeValue("cn", username);
+ context.setAttributeValue("sn", username);
+ context.setAttributeValue("userPassword", digestSHA(password));
+
+ ldapTemplate.bind(context);
+ }
+
+ public void modify(final String username, final String password) {
+ Name dn = LdapNameBuilder
+ .newInstance()
+ .add("ou", "users")
+ .add("cn", username)
+ .build();
+ DirContextOperations context = ldapTemplate.lookupContext(dn);
+
+ context.setAttributeValues("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" });
+ context.setAttributeValue("cn", username);
+ context.setAttributeValue("sn", username);
+ context.setAttributeValue("userPassword", digestSHA(password));
+
+ ldapTemplate.modifyAttributes(context);
+ }
+
+ private String digestSHA(final String password) {
+ String base64;
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA");
+ digest.update(password.getBytes());
+ base64 = Base64
+ .getEncoder()
+ .encodeToString(digest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return "{SHA}" + base64;
+ }
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java
new file mode 100644
index 0000000000..39d4df1cd6
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java
@@ -0,0 +1,66 @@
+package com.baeldung.ldap.data.service;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ldap.support.LdapUtils;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.ldap.data.repository.User;
+import com.baeldung.ldap.data.repository.UserRepository;
+
+@Service
+public class UserService {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ public Boolean authenticate(final String username, final String password) {
+ User user = userRepository.findByUsernameAndPassword(username, password);
+ return user != null ? true : false;
+ }
+
+ public List search(final String username) {
+ List userList = userRepository.findByUsernameLikeIgnoreCase(username);
+ List users = null;
+ if (null != userList) {
+ users = new ArrayList();
+ for (User user : userList) {
+ users.add(user.getUsername());
+ }
+ }
+ return users;
+
+ }
+
+ public void create(final String username, final String password) {
+ User newUser = new User(username,digestSHA(password));
+ newUser.setId(LdapUtils.emptyLdapName());
+ userRepository.save(newUser);
+
+ }
+
+ public void modify(final String username, final String password) {
+ User user = userRepository.findByUsername(username);
+ user.setPassword(password);
+ userRepository.save(user);
+
+ }
+
+ private String digestSHA(final String password) {
+ String base64;
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA");
+ digest.update(password.getBytes());
+ base64 = Base64.getEncoder()
+ .encodeToString(digest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return "{SHA}" + base64;
+ }
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java b/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
index 8572e5d1be..9330da7ab7 100644
--- a/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
@@ -7,6 +7,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
+import org.springframework.data.ldap.repository.config.EnableLdapRepositories;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
@@ -16,6 +17,7 @@ import com.baeldung.ldap.client.LdapClient;
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = { "com.baeldung.ldap.*" })
@Profile("default")
+@EnableLdapRepositories(basePackages="com.baeldung.ldap.**")
public class AppConfig {
@Autowired
diff --git a/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java
new file mode 100644
index 0000000000..8460fb3eb9
--- /dev/null
+++ b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.ldap.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.baeldung.ldap.data.service.UserService;
+import com.baeldung.ldap.javaconfig.TestConfig;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ActiveProfiles("testlive")
+@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class LdapDataRepositoryTest {
+
+ private static final String USER2 = "TEST02";
+ private static final String USER3 = "TEST03";
+ private static final String USER4 = "TEST04";
+
+ private static final String USER2_PWD = "TEST02";
+ private static final String USER3_PWD = "TEST03";
+ private static final String USER4_PWD = "TEST04";
+
+ private static final String SEARCH_STRING = "TEST*";
+
+ @Autowired
+ private UserService userService;
+
+ @Test
+ public void givenLdapClient_whenCorrectCredentials_thenSuccessfulLogin() {
+ Boolean isValid = userService.authenticate(USER3, USER3_PWD);
+ assertEquals(true, isValid);
+ }
+
+ @Test
+ public void givenLdapClient_whenIncorrectCredentials_thenFailedLogin() {
+ Boolean isValid = userService.authenticate(USER3, USER2_PWD);
+ assertEquals(false, isValid);
+ }
+
+ @Test
+ public void givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() {
+ List userList = userService.search(SEARCH_STRING);
+ assertThat(userList, Matchers.containsInAnyOrder(USER2, USER3));
+ }
+
+ @Test
+ public void givenLdapClientNotExists_whenDataProvided_thenNewUserCreated() {
+ userService.create(USER4, USER4_PWD);
+ userService.authenticate(USER4, USER4_PWD);
+ }
+
+ @Test
+ public void givenLdapClientExists_whenDataProvided_thenExistingUserModified() {
+ userService.modify(USER2, USER3_PWD);
+ userService.authenticate(USER2, USER3_PWD);
+ }
+
+}
diff --git a/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java b/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
index e2968e977c..0752262159 100644
--- a/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
+++ b/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
@@ -8,6 +8,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
+import org.springframework.data.ldap.repository.config.EnableLdapRepositories;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.test.TestContextSourceFactoryBean;
@@ -17,6 +18,7 @@ import com.baeldung.ldap.client.LdapClient;
@Configuration
@PropertySource("classpath:test_application.properties")
@ComponentScan(basePackages = { "com.baeldung.ldap.*" })
+@EnableLdapRepositories(basePackages="com.baeldung.ldap.**")
@Profile("testlive")
public class TestConfig {
@Autowired