@@ -120,14 +120,39 @@ depenendencies {
120
120
----
121
121
====
122
122
123
- You can then configure the Embedded LDAP Server:
123
+ You can then configure the Embedded LDAP Server using an `EmbeddedLdapServerContextSourceFactoryBean`.
124
+ This will instruct Spring Security to start an in-memory LDAP server:
124
125
125
126
.Embedded LDAP Server Configuration
126
127
====
127
128
.Java
128
129
[source,java,role="primary"]
129
130
----
130
131
@Bean
132
+ public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
133
+ return EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
134
+ }
135
+ ----
136
+
137
+ .Kotlin
138
+ [source,kotlin,role="secondary"]
139
+ ----
140
+ @Bean
141
+ fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
142
+ return EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
143
+ }
144
+ ----
145
+ ====
146
+
147
+ Alternatively, you can manually configure the Embedded LDAP Server.
148
+ If you choose this approach, you will be responsible for managing the lifecycle of the Embedded LDAP Server.
149
+
150
+ .Explicit Embedded LDAP Server Configuration
151
+ ====
152
+ .Java
153
+ [source,java,role="primary"]
154
+ ----
155
+ @Bean
131
156
UnboundIdContainer ldapContainer() {
132
157
return new UnboundIdContainer("dc=springframework,dc=org",
133
158
"classpath:users.ldif");
@@ -229,7 +254,36 @@ fun ldapContainer(): ApacheDSContainer {
229
254
== LDAP ContextSource
230
255
231
256
Once you have an LDAP Server to which to point your configuration, you need to configure Spring Security to point to an LDAP server that should be used to authenticate users.
232
- To do so, create an LDAP `ContextSource` (which is the equivalent of a JDBC `DataSource`):
257
+ To do so, create an LDAP `ContextSource` (which is the equivalent of a JDBC `DataSource`).
258
+ If you have already configured an `EmbeddedLdapServerContextSourceFactoryBean`, Spring Security will create an LDAP `ContextSource` that points to the embedded LDAP server.
259
+
260
+ .LDAP Context Source with Embedded LDAP Server
261
+ ====
262
+ .Java
263
+ [source,java,role="primary"]
264
+ ----
265
+ @Bean
266
+ public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
267
+ EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
268
+ EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
269
+ contextSourceFactoryBean.setPort(0);
270
+ return contextSourceFactoryBean;
271
+ }
272
+ ----
273
+
274
+ .Kotlin
275
+ [source,kotlin,role="secondary"]
276
+ ----
277
+ @Bean
278
+ fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
279
+ val contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
280
+ contextSourceFactoryBean.setPort(0)
281
+ return contextSourceFactoryBean
282
+ }
283
+ ----
284
+ ====
285
+
286
+ Alternatively, you can explicitly configure the LDAP `ContextSource` to connect to the supplied LDAP server:
233
287
234
288
.LDAP Context Source
235
289
====
@@ -288,15 +342,10 @@ The following example shows bind authentication configuration:
288
342
[source,java,role="primary",attrs="-attributes"]
289
343
----
290
344
@Bean
291
- BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
292
- BindAuthenticator authenticator = new BindAuthenticator(contextSource);
293
- authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" });
294
- return authenticator;
295
- }
296
-
297
- @Bean
298
- LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
299
- return new LdapAuthenticationProvider(authenticator);
345
+ AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
346
+ LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
347
+ factory.setUserDnPatterns("uid={0},ou=people");
348
+ return factory.createAuthenticationManager();
300
349
}
301
350
----
302
351
@@ -311,15 +360,10 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
311
360
[source,kotlin,role="secondary",attrs="-attributes"]
312
361
----
313
362
@Bean
314
- fun authenticator(contextSource: BaseLdapPathContextSource): BindAuthenticator {
315
- val authenticator = BindAuthenticator(contextSource)
316
- authenticator.setUserDnPatterns(arrayOf("uid={0},ou=people"))
317
- return authenticator
318
- }
319
-
320
- @Bean
321
- fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
322
- return LdapAuthenticationProvider(authenticator)
363
+ fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
364
+ val factory = LdapBindAuthenticationManagerFactory(contextSource)
365
+ factory.setUserDnPatterns("uid={0},ou=people")
366
+ return factory.createAuthenticationManager()
323
367
}
324
368
----
325
369
====
@@ -334,19 +378,11 @@ If, instead, you wish to configure an LDAP search filter to locate the user, you
334
378
[source,java,role="primary",attrs="-attributes"]
335
379
----
336
380
@Bean
337
- BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
338
- String searchBase = "ou=people";
339
- String filter = "(uid={0})";
340
- FilterBasedLdapUserSearch search =
341
- new FilterBasedLdapUserSearch(searchBase, filter, contextSource);
342
- BindAuthenticator authenticator = new BindAuthenticator(contextSource);
343
- authenticator.setUserSearch(search);
344
- return authenticator;
345
- }
346
-
347
- @Bean
348
- LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
349
- return new LdapAuthenticationProvider(authenticator);
381
+ AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
382
+ LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
383
+ factory.setUserSearchFilter("(uid={0})");
384
+ factory.setUserSearchBase("ou=people");
385
+ return factory.createAuthenticationManager();
350
386
}
351
387
----
352
388
@@ -362,18 +398,11 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
362
398
[source,kotlin,role="secondary",attrs="-attributes"]
363
399
----
364
400
@Bean
365
- fun authenticator(contextSource: BaseLdapPathContextSource): BindAuthenticator {
366
- val searchBase = "ou=people"
367
- val filter = "(uid={0})"
368
- val search = FilterBasedLdapUserSearch(searchBase, filter, contextSource)
369
- val authenticator = BindAuthenticator(contextSource)
370
- authenticator.setUserSearch(search)
371
- return authenticator
372
- }
373
-
374
- @Bean
375
- fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
376
- return LdapAuthenticationProvider(authenticator)
401
+ fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
402
+ val factory = LdapBindAuthenticationManagerFactory(contextSource)
403
+ factory.setUserSearchFilter("(uid={0})")
404
+ factory.setUserSearchBase("ou=people")
405
+ return factory.createAuthenticationManager()
377
406
}
378
407
----
379
408
====
@@ -395,13 +424,11 @@ An LDAP compare cannot be done when the password is properly hashed with a rando
395
424
[source,java,role="primary"]
396
425
----
397
426
@Bean
398
- PasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
399
- return new PasswordComparisonAuthenticator(contextSource);
400
- }
401
-
402
- @Bean
403
- LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
404
- return new LdapAuthenticationProvider(authenticator);
427
+ AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
428
+ LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
429
+ contextSource, NoOpPasswordEncoder.getInstance());
430
+ factory.setUserDnPatterns("uid={0},ou=people");
431
+ return factory.createAuthenticationManager();
405
432
}
406
433
----
407
434
@@ -418,13 +445,12 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
418
445
[source,kotlin,role="secondary"]
419
446
----
420
447
@Bean
421
- fun authenticator(contextSource: BaseLdapPathContextSource): PasswordComparisonAuthenticator {
422
- return PasswordComparisonAuthenticator(contextSource)
423
- }
424
-
425
- @Bean
426
- fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
427
- return LdapAuthenticationProvider(authenticator)
448
+ fun authenticationManager(contextSource: BaseLdapPathContextSource?): AuthenticationManager? {
449
+ val factory = LdapPasswordComparisonAuthenticationManagerFactory(
450
+ contextSource, NoOpPasswordEncoder.getInstance()
451
+ )
452
+ factory.setUserDnPatterns("uid={0},ou=people")
453
+ return factory.createAuthenticationManager()
428
454
}
429
455
----
430
456
====
@@ -437,17 +463,12 @@ The following example shows a more advanced configuration with some customizatio
437
463
[source,java,role="primary"]
438
464
----
439
465
@Bean
440
- PasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) {
441
- PasswordComparisonAuthenticator authenticator =
442
- new PasswordComparisonAuthenticator(contextSource);
443
- authenticator.setPasswordAttributeName("pwd"); // <1>
444
- authenticator.setPasswordEncoder(new BCryptPasswordEncoder()); // <2>
445
- return authenticator;
446
- }
447
-
448
- @Bean
449
- LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
450
- return new LdapAuthenticationProvider(authenticator);
466
+ AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
467
+ LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
468
+ contextSource, new BCryptPasswordEncoder());
469
+ factory.setUserDnPatterns("uid={0},ou=people");
470
+ factory.setPasswordAttribute("pwd"); // <1>
471
+ return factory.createAuthenticationManager();
451
472
}
452
473
----
453
474
@@ -468,23 +489,18 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
468
489
[source,kotlin,role="secondary"]
469
490
----
470
491
@Bean
471
- fun authenticator(contextSource: BaseLdapPathContextSource): PasswordComparisonAuthenticator {
472
- val authenticator = PasswordComparisonAuthenticator(contextSource)
473
- authenticator.setPasswordAttributeName("pwd") // <1>
474
- authenticator.setPasswordEncoder(BCryptPasswordEncoder()) // <2>
475
- return authenticator
476
- }
477
-
478
- @Bean
479
- fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
480
- return LdapAuthenticationProvider(authenticator)
492
+ fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
493
+ val factory = LdapPasswordComparisonAuthenticationManagerFactory(
494
+ contextSource, BCryptPasswordEncoder()
495
+ )
496
+ factory.setUserDnPatterns("uid={0},ou=people")
497
+ factory.setPasswordAttribute("pwd") // <1>
498
+ return factory.createAuthenticationManager()
481
499
}
482
500
----
483
501
====
484
502
485
503
<1> Specify the password attribute as `pwd`.
486
- <2> Use `BCryptPasswordEncoder`.
487
-
488
504
489
505
== LdapAuthoritiesPopulator
490
506
@@ -506,8 +522,11 @@ LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {
506
522
}
507
523
508
524
@Bean
509
- LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authorities) {
510
- return new LdapAuthenticationProvider(authenticator, authorities);
525
+ AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) {
526
+ LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
527
+ factory.setUserDnPatterns("uid={0},ou=people");
528
+ factory.setLdapAuthoritiesPopulator(authorities);
529
+ return factory.createAuthenticationManager();
511
530
}
512
531
----
513
532
@@ -531,8 +550,13 @@ fun authorities(contextSource: BaseLdapPathContextSource): LdapAuthoritiesPopula
531
550
}
532
551
533
552
@Bean
534
- fun authenticationProvider(authenticator: LdapAuthenticator, authorities: LdapAuthoritiesPopulator): LdapAuthenticationProvider {
535
- return LdapAuthenticationProvider(authenticator, authorities)
553
+ fun authenticationManager(
554
+ contextSource: BaseLdapPathContextSource,
555
+ authorities: LdapAuthoritiesPopulator): AuthenticationManager {
556
+ val factory = LdapBindAuthenticationManagerFactory(contextSource)
557
+ factory.setUserDnPatterns("uid={0},ou=people")
558
+ factory.setLdapAuthoritiesPopulator(authorities)
559
+ return factory.createAuthenticationManager()
536
560
}
537
561
----
538
562
====
0 commit comments