Skip to content

Commit 90ec13b

Browse files
authored
Merge pull request eugenp#11408 from synaptrec/BAEL-4451_LDAP_Authentication_using_Pure_Java
For 3rd PR (POM fixed) - [BAEL-4451] LDAP Authentication using Pure Java
2 parents af10e5a + 1ae5a53 commit 90ec13b

4 files changed

Lines changed: 211 additions & 0 deletions

File tree

core-java-modules/core-java-jndi/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@
4141
<artifactId>h2</artifactId>
4242
<version>${h2.version}</version>
4343
</dependency>
44+
<dependency>
45+
<groupId>org.apache.directory.server</groupId>
46+
<artifactId>apacheds-test-framework</artifactId>
47+
<version>${apacheds.version}</version>
48+
<scope>test</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.assertj</groupId>
52+
<artifactId>assertj-core</artifactId>
53+
<version>3.21.0</version>
54+
<scope>test</scope>
55+
</dependency>
4456
</dependencies>
4557

4658
<build>
@@ -59,6 +71,7 @@
5971
<properties>
6072
<spring.version>5.0.9.RELEASE</spring.version>
6173
<h2.version>1.4.199</h2.version>
74+
<apacheds.version>2.0.0.AM26</apacheds.version>
6275
<source.version>1.8</source.version>
6376
<target.version>1.8</target.version>
6477
</properties>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.baeldung.jndi.ldap.auth;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatCode;
5+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
6+
7+
import java.util.Hashtable;
8+
9+
import javax.naming.AuthenticationException;
10+
import javax.naming.Context;
11+
import javax.naming.NamingEnumeration;
12+
import javax.naming.directory.Attributes;
13+
import javax.naming.directory.DirContext;
14+
import javax.naming.directory.InitialDirContext;
15+
import javax.naming.directory.SearchControls;
16+
import javax.naming.directory.SearchResult;
17+
18+
import org.apache.directory.server.annotations.CreateLdapServer;
19+
import org.apache.directory.server.annotations.CreateTransport;
20+
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
21+
import org.apache.directory.server.core.annotations.CreateDS;
22+
import org.apache.directory.server.core.annotations.CreatePartition;
23+
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
24+
import org.apache.directory.server.core.integ.FrameworkRunner;
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
28+
@RunWith(FrameworkRunner.class)
29+
@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost", port = 10390)})
30+
@CreateDS(
31+
allowAnonAccess = false, partitions = {@CreatePartition(name = "TestPartition", suffix = "dc=baeldung,dc=com")})
32+
@ApplyLdifFiles({"users.ldif"})
33+
// class marked as manual test, as it has to run independently from the other unit tests in the module
34+
public class JndiLdapAuthManualTest extends AbstractLdapTestUnit {
35+
36+
private static void authenticateUser(Hashtable<String, String> environment) throws Exception {
37+
DirContext context = new InitialDirContext(environment);
38+
context.close();
39+
}
40+
41+
@Test
42+
public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
43+
44+
Hashtable<String, String> environment = new Hashtable<String, String>();
45+
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
46+
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
47+
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
48+
49+
environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
50+
environment.put(Context.SECURITY_CREDENTIALS, "12345");
51+
52+
assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
53+
}
54+
55+
@Test
56+
public void givenPreloadedLDAPUserJoe_whenAuthUserWithWrongPW_thenAuthFails() throws Exception {
57+
58+
Hashtable<String, String> environment = new Hashtable<String, String>();
59+
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
60+
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
61+
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
62+
63+
environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
64+
environment.put(Context.SECURITY_CREDENTIALS, "wronguserpw");
65+
66+
assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
67+
}
68+
69+
@Test
70+
public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
71+
72+
// first authenticate against LDAP as admin to search up DN of user : Joe Simms
73+
74+
Hashtable<String, String> environment = new Hashtable<String, String>();
75+
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
76+
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
77+
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
78+
environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
79+
environment.put(Context.SECURITY_CREDENTIALS, "secret");
80+
81+
DirContext adminContext = new InitialDirContext(environment);
82+
83+
// define the search filter to find the person with CN : Joe Simms
84+
String filter = "(&(objectClass=person)(cn=Joe Simms))";
85+
86+
// declare the attributes we want returned for the object being searched
87+
String[] attrIDs = { "cn" };
88+
89+
// define the search controls
90+
SearchControls searchControls = new SearchControls();
91+
searchControls.setReturningAttributes(attrIDs);
92+
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
93+
94+
// search for User with filter cn=Joe Simms
95+
NamingEnumeration<SearchResult> searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
96+
if (searchResults.hasMore()) {
97+
98+
SearchResult result = (SearchResult) searchResults.next();
99+
Attributes attrs = result.getAttributes();
100+
101+
String distinguishedName = result.getNameInNamespace();
102+
assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
103+
104+
String commonName = attrs.get("cn").toString();
105+
assertThat(commonName).isEqualTo("cn: Joe Simms");
106+
107+
// authenticate new context with DN for user Joe Simms, using correct password
108+
109+
environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
110+
environment.put(Context.SECURITY_CREDENTIALS, "12345");
111+
112+
assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
113+
}
114+
115+
adminContext.close();
116+
}
117+
118+
@Test
119+
public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithWrongPW_thenAuthFails() throws Exception {
120+
121+
// first authenticate against LDAP as admin to search up DN of user : Joe Simms
122+
123+
Hashtable<String, String> environment = new Hashtable<String, String>();
124+
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
125+
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
126+
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
127+
environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
128+
environment.put(Context.SECURITY_CREDENTIALS, "secret");
129+
DirContext adminContext = new InitialDirContext(environment);
130+
131+
// define the search filter to find the person with CN : Joe Simms
132+
String filter = "(&(objectClass=person)(cn=Joe Simms))";
133+
134+
// declare the attributes we want returned for the object being searched
135+
String[] attrIDs = { "cn" };
136+
137+
// define the search controls
138+
SearchControls searchControls = new SearchControls();
139+
searchControls.setReturningAttributes(attrIDs);
140+
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
141+
142+
// search for User with filter cn=Joe Simms
143+
NamingEnumeration<SearchResult> searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
144+
if (searchResults.hasMore()) {
145+
146+
SearchResult result = (SearchResult) searchResults.next();
147+
Attributes attrs = result.getAttributes();
148+
149+
String distinguishedName = result.getNameInNamespace();
150+
assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
151+
152+
String commonName = attrs.get("cn").toString();
153+
assertThat(commonName).isEqualTo("cn: Joe Simms");
154+
155+
// authenticate new context with DN for user Joe Simms, using wrong password
156+
157+
environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
158+
environment.put(Context.SECURITY_CREDENTIALS, "wronguserpassword");
159+
160+
assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
161+
}
162+
163+
adminContext.close();
164+
}
165+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
4+
<encoder>
5+
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
6+
</pattern>
7+
</encoder>
8+
</appender>
9+
10+
<root level="WARN">
11+
<appender-ref ref="STDOUT" />
12+
</root>
13+
</configuration>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
version: 1
2+
dn: dc=baeldung,dc=com
3+
objectClass: domain
4+
objectClass: top
5+
dc: baeldung
6+
7+
dn: ou=Users,dc=baeldung,dc=com
8+
objectClass: organizationalUnit
9+
objectClass: top
10+
ou: Users
11+
12+
dn: cn=Joe Simms,ou=Users,dc=baeldung,dc=com
13+
objectClass: inetOrgPerson
14+
objectClass: organizationalPerson
15+
objectClass: person
16+
objectClass: top
17+
cn: Joe Simms
18+
sn: Simms
19+
uid: user1
20+
userPassword: 12345

0 commit comments

Comments
 (0)