0
# Context Management
1
2
LDAP context source and template classes for managing connections to LDAP servers with support for authentication, connection pooling, and operation execution.
3
4
## Capabilities
5
6
### DefaultSpringSecurityContextSource
7
8
Spring Security's LDAP context source implementation providing connection management and authentication for LDAP operations.
9
10
```java { .api }
11
/**
12
* Default LDAP context source implementation for Spring Security providing connection management
13
* and authentication support for LDAP directory operations
14
*/
15
public class DefaultSpringSecurityContextSource implements InitializingBean, DisposableBean {
16
/**
17
* Creates an LDAP context source with the specified provider URL
18
* @param providerUrl the LDAP URL (e.g., "ldap://localhost:389/dc=springframework,dc=org")
19
*/
20
public DefaultSpringSecurityContextSource(String providerUrl);
21
22
/**
23
* Creates an LDAP context source with provider URL and base DN
24
* @param providerUrl the LDAP URL
25
* @param baseDn the base distinguished name for operations
26
*/
27
public DefaultSpringSecurityContextSource(String providerUrl, String baseDn);
28
29
/**
30
* Creates an LDAP context source from a list of URLs for failover support
31
* @param urls list of LDAP URLs for failover
32
* @param baseDn the base distinguished name
33
*/
34
public DefaultSpringSecurityContextSource(List<String> urls, String baseDn);
35
36
/**
37
* Sets the distinguished name for the manager user
38
* @param userDn the manager user DN (e.g., "cn=manager,dc=springframework,dc=org")
39
*/
40
public void setUserDn(String userDn);
41
42
/**
43
* Sets the password for the manager user
44
* @param password the manager password
45
*/
46
public void setPassword(String password);
47
48
/**
49
* Gets a read-only LDAP context for search operations
50
* @return DirContext for read-only operations
51
* @throws NamingException if context creation fails
52
*/
53
public DirContext getReadOnlyContext() throws NamingException;
54
55
/**
56
* Gets a read-write LDAP context for modification operations
57
* @return DirContext for read-write operations
58
* @throws NamingException if context creation fails
59
*/
60
public DirContext getReadWriteContext() throws NamingException;
61
62
/**
63
* Gets an authenticated context using the provided credentials
64
* @param principal the authentication principal (username or DN)
65
* @param credentials the authentication credentials (password)
66
* @return DirContext authenticated with provided credentials
67
* @throws NamingException if authentication fails
68
*/
69
public DirContext getContext(String principal, String credentials) throws NamingException;
70
71
/**
72
* Sets the LDAP connection pool configuration
73
* @param pooled true to enable connection pooling
74
*/
75
public void setPooled(boolean pooled);
76
77
/**
78
* Sets the referral handling strategy
79
* @param referral the referral strategy ("follow", "ignore", or "throw")
80
*/
81
public void setReferral(String referral);
82
83
/**
84
* Sets additional LDAP environment properties
85
* @param baseEnvironmentProperties map of LDAP environment properties
86
*/
87
public void setBaseEnvironmentProperties(Map<String, Object> baseEnvironmentProperties);
88
}
89
```
90
91
**Usage Examples:**
92
93
```java
94
// Basic context source configuration
95
DefaultSpringSecurityContextSource contextSource =
96
new DefaultSpringSecurityContextSource("ldap://localhost:389/dc=springframework,dc=org");
97
contextSource.setUserDn("cn=manager,dc=springframework,dc=org");
98
contextSource.setPassword("password");
99
contextSource.afterPropertiesSet();
100
101
// Failover configuration with multiple URLs
102
List<String> urls = Arrays.asList(
103
"ldap://ldap1.example.com:389",
104
"ldap://ldap2.example.com:389"
105
);
106
DefaultSpringSecurityContextSource contextSource =
107
new DefaultSpringSecurityContextSource(urls, "dc=example,dc=com");
108
109
// With connection pooling and referral handling
110
contextSource.setPooled(true);
111
contextSource.setReferral("follow");
112
113
// Custom environment properties
114
Map<String, Object> env = new HashMap<>();
115
env.put("java.naming.ldap.connect.timeout", "5000");
116
env.put("java.naming.ldap.read.timeout", "10000");
117
contextSource.setBaseEnvironmentProperties(env);
118
```
119
120
### SpringSecurityLdapTemplate
121
122
LDAP template class providing high-level operations for common LDAP tasks with Spring Security integration.
123
124
```java { .api }
125
/**
126
* LDAP template class providing simplified LDAP operations with Spring Security integration
127
*/
128
public class SpringSecurityLdapTemplate {
129
/**
130
* Creates an LDAP template with the specified context source
131
* @param contextSource the LDAP context source
132
*/
133
public SpringSecurityLdapTemplate(ContextSource contextSource);
134
135
/**
136
* Searches for a single entry matching the specified criteria
137
* @param base the base DN for the search
138
* @param filter the LDAP search filter
139
* @param params parameters to substitute in the filter
140
* @return DirContextOperations representing the found entry
141
* @throws IncorrectResultSizeDataAccessException if multiple entries found
142
*/
143
public DirContextOperations searchForSingleEntry(String base, String filter, Object[] params);
144
145
/**
146
* Searches for a context matching the specified criteria
147
* @param base the base DN for the search
148
* @param filter the LDAP search filter
149
* @param params parameters to substitute in the filter
150
* @return DirContextOperations representing the found context
151
*/
152
public DirContextOperations searchForContext(String base, String filter, Object[] params);
153
154
/**
155
* Searches for all entries matching the specified criteria
156
* @param base the base DN for the search
157
* @param filter the LDAP search filter
158
* @param params parameters to substitute in the filter
159
* @param mapper mapper for converting search results
160
* @return set of mapped results
161
*/
162
public <T> Set<T> searchForSingleAttributeValues(String base, String filter, Object[] params,
163
String attributeName);
164
165
/**
166
* Performs authentication by attempting to bind with provided credentials
167
* @param base the base DN for the search
168
* @param filter the LDAP search filter to find the user
169
* @param params parameters to substitute in the filter
170
* @param password the password to authenticate with
171
* @return true if authentication successful
172
*/
173
public boolean authenticate(String base, String filter, Object[] params, String password);
174
175
/**
176
* Compares an attribute value against the stored value in LDAP
177
* @param dn the distinguished name of the entry
178
* @param attributeName the attribute to compare
179
* @param value the value to compare against
180
* @return true if values match
181
*/
182
public boolean compare(String dn, String attributeName, Object value);
183
184
/**
185
* Modifies LDAP entry attributes
186
* @param dn the distinguished name of the entry to modify
187
* @param mods array of modification items
188
*/
189
public void modifyAttributes(String dn, ModificationItem[] mods);
190
191
/**
192
* Sets the search controls for LDAP operations
193
* @param searchControls the search controls to use
194
*/
195
public void setSearchControls(SearchControls searchControls);
196
197
/**
198
* Sets whether to ignore size limits during searches
199
* @param ignoreSizeLimitExceededExceptions true to ignore size limit exceptions
200
*/
201
public void setIgnorePartialResultException(boolean ignoreSizeLimitExceededExceptions);
202
}
203
```
204
205
**Usage Examples:**
206
207
```java
208
// Basic template usage
209
SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(contextSource);
210
211
// Search for single user
212
DirContextOperations user = template.searchForSingleEntry(
213
"ou=people", "uid={0}", new Object[]{"johndoe"});
214
215
// Authenticate user
216
boolean authenticated = template.authenticate(
217
"ou=people", "uid={0}", new Object[]{"johndoe"}, "password");
218
219
// Search for attribute values
220
Set<String> emails = template.searchForSingleAttributeValues(
221
"ou=people", "department={0}", new Object[]{"IT"}, "mail");
222
223
// Compare attribute value
224
boolean isActive = template.compare("uid=johndoe,ou=people", "active", "true");
225
```
226
227
### LdapUtils
228
229
Utility class providing static helper methods for common LDAP operations and DN manipulation.
230
231
```java { .api }
232
/**
233
* Utility class providing static helper methods for LDAP operations and DN manipulation
234
*/
235
public final class LdapUtils {
236
/**
237
* Extracts the relative DN from a full DN given a base DN
238
* @param baseDn the base distinguished name
239
* @param fullDn the full distinguished name
240
* @return the relative DN as a string
241
*/
242
public static String getRelativeName(String baseDn, String fullDn);
243
244
/**
245
* Builds a full DN from a relative DN and base DN
246
* @param dn the relative DN
247
* @param baseDn the base DN
248
* @return LdapName representing the full DN
249
*/
250
public static LdapName getFullDn(LdapName dn, Name baseDn);
251
252
/**
253
* Converts a NamingException to a Spring DataAccessException
254
* @param e the NamingException to convert
255
* @return DataAccessException wrapping the original exception
256
*/
257
public static DataAccessException convertLdapException(NamingException e);
258
259
/**
260
* Creates a new DN by adding an RDN to an existing DN
261
* @param dn the existing DN
262
* @param rdn the RDN to add
263
* @return new LdapName with the added RDN
264
*/
265
public static LdapName newLdapName(String dn);
266
267
/**
268
* Removes the first RDN from a DN
269
* @param dn the DN to modify
270
* @return new LdapName with first RDN removed
271
*/
272
public static LdapName removeFirst(LdapName dn);
273
274
/**
275
* Gets the first RDN from a DN
276
* @param dn the DN to examine
277
* @return the first RDN as a string
278
*/
279
public static String getFirstRdn(LdapName dn);
280
}
281
```
282
283
### Username to DN Mapping
284
285
Strategy interface and implementation for converting usernames to LDAP Distinguished Names.
286
287
```java { .api }
288
/**
289
* Strategy interface for mapping usernames to Distinguished Names
290
*/
291
public interface LdapUsernameToDnMapper {
292
/**
293
* Builds an LDAP Distinguished Name from a username
294
* @param username the username to map
295
* @return LdapName representing the user's DN
296
*/
297
LdapName buildLdapName(String username);
298
299
/**
300
* Builds a Distinguished Name from a username (deprecated)
301
* @param username the username to map
302
* @return DistinguishedName representing the user's DN
303
* @deprecated Use buildLdapName(String) instead
304
*/
305
@Deprecated
306
DistinguishedName buildDn(String username);
307
}
308
309
/**
310
* Default implementation that appends a name component to the userDnBase context
311
* using the usernameAttributeName property
312
*/
313
public class DefaultLdapUsernameToDnMapper implements LdapUsernameToDnMapper {
314
/**
315
* Creates a default username to DN mapper
316
* @param userDnBase the base name of the DN
317
* @param usernameAttribute the attribute to append for the username component
318
*/
319
public DefaultLdapUsernameToDnMapper(String userDnBase, String usernameAttribute);
320
321
/**
322
* Builds an LDAP name from the username by appending it to the base DN
323
* @param username the username to map
324
* @return LdapName representing the user's full DN
325
*/
326
public LdapName buildLdapName(String username);
327
}
328
```
329
330
## Configuration Examples
331
332
### Basic Context Source Configuration
333
334
```java
335
@Configuration
336
@EnableWebSecurity
337
public class LdapContextConfig {
338
339
@Bean
340
public DefaultSpringSecurityContextSource contextSource() {
341
DefaultSpringSecurityContextSource contextSource =
342
new DefaultSpringSecurityContextSource("ldap://localhost:389/dc=springframework,dc=org");
343
344
// Manager authentication
345
contextSource.setUserDn("cn=manager,dc=springframework,dc=org");
346
contextSource.setPassword("password");
347
348
// Connection settings
349
contextSource.setPooled(true);
350
contextSource.setReferral("follow");
351
352
// Custom environment properties
353
Map<String, Object> baseEnv = new HashMap<>();
354
baseEnv.put("java.naming.ldap.connect.timeout", "5000");
355
baseEnv.put("java.naming.ldap.read.timeout", "10000");
356
baseEnv.put("java.naming.security.protocol", "ssl");
357
contextSource.setBaseEnvironmentProperties(baseEnv);
358
359
return contextSource;
360
}
361
362
@Bean
363
public SpringSecurityLdapTemplate ldapTemplate() {
364
SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(contextSource());
365
366
// Configure search controls
367
SearchControls searchControls = new SearchControls();
368
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
369
searchControls.setTimeLimit(5000);
370
template.setSearchControls(searchControls);
371
372
template.setIgnorePartialResultException(true);
373
return template;
374
}
375
}
376
```
377
378
### SSL/TLS Configuration
379
380
```java
381
@Bean
382
public DefaultSpringSecurityContextSource secureContextSource() {
383
DefaultSpringSecurityContextSource contextSource =
384
new DefaultSpringSecurityContextSource("ldaps://ldap.example.com:636/dc=example,dc=com");
385
386
contextSource.setUserDn("cn=admin,dc=example,dc=com");
387
contextSource.setPassword("adminPassword");
388
389
// SSL/TLS configuration
390
Map<String, Object> baseEnv = new HashMap<>();
391
baseEnv.put("java.naming.security.protocol", "ssl");
392
baseEnv.put("java.naming.ldap.factory.socket", "javax.net.ssl.SSLSocketFactory");
393
394
// Trust store configuration (if needed)
395
baseEnv.put("javax.net.ssl.trustStore", "/path/to/truststore.jks");
396
baseEnv.put("javax.net.ssl.trustStorePassword", "truststorePassword");
397
398
contextSource.setBaseEnvironmentProperties(baseEnv);
399
return contextSource;
400
}
401
```
402
403
### High Availability Configuration
404
405
```java
406
@Bean
407
public DefaultSpringSecurityContextSource haContextSource() {
408
// Multiple LDAP servers for failover
409
List<String> urls = Arrays.asList(
410
"ldap://ldap1.example.com:389",
411
"ldap://ldap2.example.com:389",
412
"ldap://ldap3.example.com:389"
413
);
414
415
DefaultSpringSecurityContextSource contextSource =
416
new DefaultSpringSecurityContextSource(urls, "dc=example,dc=com");
417
418
contextSource.setUserDn("cn=admin,dc=example,dc=com");
419
contextSource.setPassword("adminPassword");
420
421
// Connection and timeout settings
422
Map<String, Object> baseEnv = new HashMap<>();
423
baseEnv.put("java.naming.ldap.connect.timeout", "3000");
424
baseEnv.put("java.naming.ldap.read.timeout", "5000");
425
baseEnv.put("com.sun.jndi.ldap.connect.pool", "true");
426
baseEnv.put("com.sun.jndi.ldap.connect.pool.maxsize", "10");
427
baseEnv.put("com.sun.jndi.ldap.connect.pool.prefsize", "5");
428
429
contextSource.setBaseEnvironmentProperties(baseEnv);
430
return contextSource;
431
}
432
```
433
434
### Custom Template Operations
435
436
```java
437
@Service
438
public class CustomLdapService {
439
440
private final SpringSecurityLdapTemplate ldapTemplate;
441
442
public CustomLdapService(SpringSecurityLdapTemplate ldapTemplate) {
443
this.ldapTemplate = ldapTemplate;
444
}
445
446
public List<String> findUsersByDepartment(String department) {
447
return ldapTemplate.searchForSingleAttributeValues(
448
"ou=people",
449
"department={0}",
450
new Object[]{department},
451
"uid"
452
).stream().collect(Collectors.toList());
453
}
454
455
public boolean validateUserCredentials(String username, String password) {
456
return ldapTemplate.authenticate(
457
"ou=people",
458
"uid={0}",
459
new Object[]{username},
460
password
461
);
462
}
463
464
public void updateUserEmail(String username, String newEmail) {
465
String userDn = findUserDn(username);
466
ModificationItem[] mods = new ModificationItem[] {
467
new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
468
new BasicAttribute("mail", newEmail))
469
};
470
ldapTemplate.modifyAttributes(userDn, mods);
471
}
472
473
private String findUserDn(String username) {
474
DirContextOperations user = ldapTemplate.searchForSingleEntry(
475
"ou=people", "uid={0}", new Object[]{username});
476
return user.getDn().toString();
477
}
478
}
479
```