Skip to content

Commit 0a4eb0f

Browse files
committed
Update credential erasure examples
Closes gh-15683
1 parent a0e6c17 commit 0a4eb0f

File tree

1 file changed

+81
-91
lines changed
  • docs/modules/ROOT/pages/servlet/authentication/passwords

1 file changed

+81
-91
lines changed

docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc

+81-91
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,74 @@ Normally, Spring Security builds an `AuthenticationManager` internally composed
326326
In certain cases, it may still be desired to customize the instance of `AuthenticationManager` used by Spring Security.
327327
For example, you may need to simply disable xref:servlet/authentication/architecture.adoc#servlet-authentication-providermanager-erasing-credentials[credential erasure] for cached users.
328328

329-
The recommended way to do this is to simply publish your own `AuthenticationManager` bean, and Spring Security will use it.
330-
You can publish an `AuthenticationManager` using the following configuration:
329+
To do this, you can take advantage of the fact that the `AuthenticationManagerBuilder` used to build Spring Security's global `AuthenticationManager` is published as a bean.
330+
You can configure the builder as follows:
331+
332+
.Configure global `AuthenticationManagerBuilder`
333+
[tabs]
334+
=====
335+
Java::
336+
+
337+
[source,java,role="primary"]
338+
----
339+
@Configuration
340+
@EnableWebSecurity
341+
public class SecurityConfig {
342+
343+
@Bean
344+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
345+
// ...
346+
return http.build();
347+
}
348+
349+
@Bean
350+
public UserDetailsService userDetailsService() {
351+
// Return a UserDetailsService that caches users
352+
// ...
353+
}
354+
355+
@Autowired
356+
public void configure(AuthenticationManagerBuilder builder) {
357+
builder.eraseCredentials(false);
358+
}
359+
360+
}
361+
----
362+
363+
Kotlin::
364+
+
365+
[source,kotlin,role="secondary"]
366+
----
367+
import org.springframework.security.config.annotation.web.invoke
331368
332-
.Publish `AuthenticationManager` bean for Spring Security
369+
@Configuration
370+
@EnableWebSecurity
371+
class SecurityConfig {
372+
373+
@Bean
374+
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
375+
// ...
376+
return http.build()
377+
}
378+
379+
@Bean
380+
fun userDetailsService(): UserDetailsService {
381+
// Return a UserDetailsService that caches users
382+
// ...
383+
}
384+
385+
@Autowired
386+
fun configure(builder: AuthenticationManagerBuilder) {
387+
builder.eraseCredentials(false)
388+
}
389+
390+
}
391+
----
392+
=====
393+
394+
Alternatively, you may configure a local `AuthenticationManager` to override the global one.
395+
396+
.Configure local `AuthenticationManager` for Spring Security
333397
[tabs]
334398
=====
335399
Java::
@@ -344,31 +408,27 @@ public class SecurityConfig {
344408
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
345409
http
346410
.authorizeHttpRequests((authorize) -> authorize
347-
.requestMatchers("/login").permitAll()
348411
.anyRequest().authenticated()
349412
)
350413
.httpBasic(Customizer.withDefaults())
351-
.formLogin(Customizer.withDefaults());
414+
.formLogin(Customizer.withDefaults())
415+
.authenticationManager(authenticationManager());
352416
353417
return http.build();
354418
}
355419
356-
@Bean
357-
public AuthenticationManager authenticationManager(
358-
UserDetailsService userDetailsService,
359-
PasswordEncoder passwordEncoder) {
420+
private AuthenticationManager authenticationManager() {
360421
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
361-
authenticationProvider.setUserDetailsService(userDetailsService);
362-
authenticationProvider.setPasswordEncoder(passwordEncoder);
422+
authenticationProvider.setUserDetailsService(userDetailsService());
423+
authenticationProvider.setPasswordEncoder(passwordEncoder());
363424
364425
ProviderManager providerManager = new ProviderManager(authenticationProvider);
365426
providerManager.setEraseCredentialsAfterAuthentication(false);
366427
367428
return providerManager;
368429
}
369430
370-
@Bean
371-
public UserDetailsService userDetailsService() {
431+
private UserDetailsService userDetailsService() {
372432
UserDetails userDetails = User.withDefaultPasswordEncoder()
373433
.username("user")
374434
.password("password")
@@ -378,8 +438,7 @@ public class SecurityConfig {
378438
return new InMemoryUserDetailsManager(userDetails);
379439
}
380440
381-
@Bean
382-
public PasswordEncoder passwordEncoder() {
441+
private PasswordEncoder passwordEncoder() {
383442
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
384443
}
385444
@@ -390,8 +449,7 @@ XML::
390449
+
391450
[source,xml,role="secondary"]
392451
----
393-
<http>
394-
<intercept-url pattern="/login" access="permitAll"/>
452+
<http authentication-manager-ref="authenticationManager">
395453
<intercept-url pattern="/**" access="authenticated"/>
396454
<form-login />
397455
<http-basic />
@@ -431,32 +489,29 @@ class SecurityConfig {
431489
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
432490
http {
433491
authorizeHttpRequests {
434-
authorize("/login", permitAll)
435492
authorize(anyRequest, authenticated)
436493
}
437494
formLogin { }
438495
httpBasic { }
496+
authenticationManager = authenticationManager()
439497
}
440498
441499
return http.build()
442500
}
443501
444502
@Bean
445-
fun authenticationManager(
446-
userDetailsService: UserDetailsService,
447-
passwordEncoder: PasswordEncoder): AuthenticationManager {
503+
fun authenticationManager(): AuthenticationManager {
448504
val authenticationProvider = DaoAuthenticationProvider()
449-
authenticationProvider.setUserDetailsService(userDetailsService)
450-
authenticationProvider.setPasswordEncoder(passwordEncoder)
505+
authenticationProvider.setUserDetailsService(userDetailsService())
506+
authenticationProvider.setPasswordEncoder(passwordEncoder())
451507
452508
val providerManager = ProviderManager(authenticationProvider)
453509
providerManager.eraseCredentialsAfterAuthentication = false
454510
455511
return providerManager
456512
}
457513
458-
@Bean
459-
fun userDetailsService(): UserDetailsService {
514+
private fun userDetailsService(): UserDetailsService {
460515
val user = User.withDefaultPasswordEncoder()
461516
.username("user")
462517
.password("password")
@@ -466,76 +521,11 @@ class SecurityConfig {
466521
return InMemoryUserDetailsManager(user)
467522
}
468523
469-
@Bean
470-
fun passwordEncoder(): PasswordEncoder {
524+
private fun passwordEncoder(): PasswordEncoder {
471525
return PasswordEncoderFactories.createDelegatingPasswordEncoder()
472526
}
473527
474528
}
475529
----
476530
=====
477531

478-
Alternatively, you can take advantage of the fact that the `AuthenticationManagerBuilder` used to build Spring Security's global `AuthenticationManager` is published as a bean.
479-
You can configure the builder as follows:
480-
481-
.Configure global `AuthenticationManagerBuilder`
482-
[tabs]
483-
=====
484-
Java::
485-
+
486-
[source,java,role="primary"]
487-
----
488-
@Configuration
489-
@EnableWebSecurity
490-
public class SecurityConfig {
491-
492-
@Bean
493-
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
494-
// ...
495-
return http.build();
496-
}
497-
498-
@Bean
499-
public UserDetailsService userDetailsService() {
500-
// Return a UserDetailsService that caches users
501-
// ...
502-
}
503-
504-
@Autowired
505-
public void configure(AuthenticationManagerBuilder builder) {
506-
builder.eraseCredentials(false);
507-
}
508-
509-
}
510-
----
511-
512-
Kotlin::
513-
+
514-
[source,kotlin,role="secondary"]
515-
----
516-
import org.springframework.security.config.annotation.web.invoke
517-
518-
@Configuration
519-
@EnableWebSecurity
520-
class SecurityConfig {
521-
522-
@Bean
523-
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
524-
// ...
525-
return http.build()
526-
}
527-
528-
@Bean
529-
fun userDetailsService(): UserDetailsService {
530-
// Return a UserDetailsService that caches users
531-
// ...
532-
}
533-
534-
@Autowired
535-
fun configure(builder: AuthenticationManagerBuilder) {
536-
builder.eraseCredentials(false)
537-
}
538-
539-
}
540-
----
541-
=====

0 commit comments

Comments
 (0)