| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 | 
							- = Configuration Migrations
 
- The following steps relate to changes around how to configure `HttpSecurity`, `WebSecurity`, and `AuthenticationManager`.
 
- [[add-configuration-annotation]]
 
- == Add `@Configuration` annotation
 
- In 6.0, `@Configuration` is removed from `@EnableWebSecurity`, `@EnableMethodSecurity`,  `@EnableGlobalMethodSecurity`, and `@EnableGlobalAuthentication`.
 
- To prepare for this, wherever you are using one of these annotations, you may need to add `@Configuration`.
 
- For example, `@EnableMethodSecurity` changes from:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @EnableMethodSecurity
 
- public class MyConfiguration {
 
- 	// ...
 
- }
 
- ----
 
- .Kotlin
 
- [source,java,role="primary"]
 
- ----
 
- @EnableMethodSecurity
 
- open class MyConfiguration {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- to:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableMethodSecurity
 
- public class MyConfiguration {
 
- 	// ...
 
- }
 
- ----
 
- .Kotlin
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableMethodSecurity
 
- open class MyConfiguration {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- [[use-new-requestmatchers]]
 
- == Use the new `requestMatchers` methods
 
- In Spring Security 5.8, the {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#antMatchers(java.lang.String...)[`antMatchers`], {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#mvcMatchers(java.lang.String...)[`mvcMatchers`], and {security-api-url}org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.html#regexMatchers(java.lang.String...)[`regexMatchers`] methods were deprecated in favor of new xref:servlet/authorization/authorize-http-requests.adoc#_request_matchers[`requestMatchers` methods].
 
- The new `requestMatchers` methods were added xref:servlet/authorization/authorize-http-requests.adoc[to `authorizeHttpRequests`], `authorizeRequests`, CSRF configuration, `WebSecurityCustomizer` and any other places that had the specialized `RequestMatcher` methods.
 
- The deprecated methods are removed in Spring Security 6.
 
- These new methods have more secure defaults since they choose the most appropriate `RequestMatcher` implementation for your application.
 
- In summary, the new methods choose the `MvcRequestMatcher` implementation if your application has Spring MVC in the classpath, falling back to the `AntPathRequestMatcher` implementation if Spring MVC is not present (aligning the behavior with the Kotlin equivalent methods).
 
- To start using the new methods, you can replace the deprecated methods with the new ones. For example, the following application configuration:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- public class SecurityConfig {
 
-     @Bean
 
-     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .antMatchers("/api/admin/**").hasRole("ADMIN")
 
-                 .antMatchers("/api/user/**").hasRole("USER")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- can be changed to:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- public class SecurityConfig {
 
-     @Bean
 
-     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .requestMatchers("/api/admin/**").hasRole("ADMIN")
 
-                 .requestMatchers("/api/user/**").hasRole("USER")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- If you have Spring MVC in the classpath and are using the `mvcMatchers` methods, you can replace it with the new methods and Spring Security will choose the `MvcRequestMatcher` implementation for you.
 
- The following configuration:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- @EnableWebMvc
 
- public class SecurityConfig {
 
-     @Bean
 
-     SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .mvcMatchers("/admin/**").hasRole("ADMIN")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- is equivalent to:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- @EnableWebMvc
 
- public class SecurityConfig {
 
-     @Bean
 
-     SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .requestMatchers("/admin/**").hasRole("ADMIN")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- If you are customizing the `servletPath` property of the `MvcRequestMatcher`, you can now use the `MvcRequestMatcher.Builder` to create `MvcRequestMatcher` instances that share the same servlet path:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- @EnableWebMvc
 
- public class SecurityConfig {
 
-     @Bean
 
-     SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .mvcMatchers("/admin").servletPath("/path").hasRole("ADMIN")
 
-                 .mvcMatchers("/user").servletPath("/path").hasRole("USER")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- The code above can be rewritten using the `MvcRequestMatcher.Builder` and the `requestMatchers` method:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- @EnableWebMvc
 
- public class SecurityConfig {
 
-     @Bean
 
-     SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
 
-         MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector).servletPath("/path");
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .requestMatchers(mvcMatcherBuilder.pattern("/admin")).hasRole("ADMIN")
 
-                 .requestMatchers(mvcMatcherBuilder.pattern("/user")).hasRole("USER")
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- If you are having problem with the new `requestMatchers` methods, you can always switch back to the `RequestMatcher` implementation that you were using.
 
- For example, if you still want to use `AntPathRequestMatcher` and `RegexRequestMatcher` implementations, you can use the `requestMatchers` method that accepts a `RequestMatcher` instance:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
 
- import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;
 
- @Configuration
 
- @EnableWebSecurity
 
- public class SecurityConfig {
 
-     @Bean
 
-     SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authz) -> authz
 
-                 .requestMatchers(antMatcher("/user/**")).hasRole("USER")
 
-                 .requestMatchers(antMatcher(HttpMethod.POST, "/user/**")).hasRole("ADMIN")
 
-                 .requestMatchers(regexMatcher(".*\\?x=y")).hasRole("SPECIAL") // matches /any/path?x=y
 
-                 .anyRequest().authenticated()
 
-             );
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- ====
 
- Note that the above sample uses static factory methods from {security-api-url}org/springframework/security/web/util/matcher/AntPathRequestMatcher.html[`AntPathRequestMatcher`] and {security-api-url}org/springframework/security/web/util/matcher/RegexRequestMatcher.html[`RegexRequestMatcher`] to improve readability.
 
- If you are using the `WebSecurityCustomizer` interface, you can replace the deprecated `antMatchers` methods:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public WebSecurityCustomizer webSecurityCustomizer() {
 
- 	return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
 
- }
 
- ----
 
- ====
 
- with their `requestMatchers` counterparts:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public WebSecurityCustomizer webSecurityCustomizer() {
 
- 	return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
 
- }
 
- ----
 
- ====
 
- The same way, if you are customizing the CSRF configuration to ignore some paths, you can replace the deprecated methods with the `requestMatchers` methods:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .csrf((csrf) -> csrf
 
-             .ignoringAntMatchers("/no-csrf")
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- can be changed to:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .csrf((csrf) -> csrf
 
-             .ignoringRequestMatchers("/no-csrf")
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- [[use-new-security-matchers]]
 
- == Use the new `securityMatchers` methods
 
- In Spring Security 5.8, the `antMatchers`, `mvcMatchers` and `requestMatchers` methods from `HttpSecurity` were deprecated in favor of new `securityMatchers` methods.
 
- Note that these methods are not the same from `authorizeHttpRequests` methods <<use-new-requestmatchers,which were deprecated>> in favor of the `requestMatchers` methods.
 
- However, the `securityMatchers` methods are similar to the `requestMatchers` methods in the sense that they will choose the most appropriate `RequestMatcher` implementation for your application.
 
- In summary, the new methods choose the `MvcRequestMatcher` implementation if your application has Spring MVC in the classpath, falling back to the `AntPathRequestMatcher` implementation if Spring MVC is not present (aligning the behavior with the Kotlin equivalent methods).
 
- Another reason for adding the `securityMatchers` methods is to avoid confusion with the `requestMatchers` methods from `authorizeHttpRequests`.
 
- The following configuration:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .antMatcher("/api/**", "/app/**")
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/api/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- can be rewritten using the `securityMatchers` methods:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .securityMatcher("/api/**", "/app/**")
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/api/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- If you are using a custom `RequestMatcher` in your `HttpSecurity` configuration:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .requestMatcher(new MyCustomRequestMatcher())
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/api/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- public class MyCustomRequestMatcher implements RequestMatcher {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- you can do the same using `securityMatcher`:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .securityMatcher(new MyCustomRequestMatcher())
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/api/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- public class MyCustomRequestMatcher implements RequestMatcher {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- If you are combining multiple `RequestMatcher` implementations in your `HttpSecurity` configuration:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .requestMatchers((matchers) -> matchers
 
-             .antMatchers("/api/**", "/app/**")
 
-             .mvcMatchers("/admin/**")
 
-             .requestMatchers(new MyCustomRequestMatcher())
 
-         )
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- you can change it by using `securityMatchers`:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .securityMatchers((matchers) -> matchers
 
-             .requestMatchers("/api/**", "/app/**", "/admin/**")
 
-             .requestMatchers(new MyCustomRequestMatcher())
 
-         )
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers("/admin/**").hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- If you are having problems with the `securityMatchers` methods choosing the `RequestMatcher` implementation for you, you can always choose the `RequestMatcher` implementation yourself:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
 
- @Bean
 
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-     http
 
-         .securityMatchers((matchers) -> matchers
 
-             .requestMatchers(antMatcher("/api/**"), antMatcher("/app/**"))
 
-         )
 
-         .authorizeHttpRequests((authz) -> authz
 
-             .requestMatchers(antMatcher("/api/admin/**")).hasRole("ADMIN")
 
-             .anyRequest().authenticated()
 
-         );
 
-     return http.build();
 
- }
 
- ----
 
- ====
 
- == Stop Using `WebSecurityConfigurerAdapter`
 
- === Publish a `SecurityFilterChain` Bean
 
- Spring Security 5.4 introduced the capability to publish a `SecurityFilterChain` bean instead of extending `WebSecurityConfigurerAdapter`.
 
- In 6.0, `WebSecurityConfigurerAdapter` is removed.
 
- To prepare for this change, you can replace constructs like:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-     @Override
 
-     protected void configure(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authorize) -> authorize
 
-                 .anyRequest().authenticated()
 
-             )
 
-             .httpBasic(withDefaults());
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
 
-     @Override
 
-     override fun configure(val http: HttpSecurity) {
 
-         http {
 
-             authorizeHttpRequests {
 
-                 authorize(anyRequest, authenticated)
 
-             }
 
-             httpBasic {}
 
-         }
 
-     }
 
- }
 
- ----
 
- ====
 
- with:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration {
 
-     @Bean
 
-     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
-         http
 
-             .authorizeHttpRequests((authorize) -> authorize
 
-                 .anyRequest().authenticated()
 
-             )
 
-             .httpBasic(withDefaults());
 
-         return http.build();
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration {
 
-     @Bean
 
-     fun filterChain(http: HttpSecurity): SecurityFilterChain {
 
-         http {
 
-             authorizeHttpRequests {
 
-                 authorize(anyRequest, authenticated)
 
-             }
 
-             httpBasic {}
 
-         }
 
-         return http.build()
 
-     }
 
- }
 
- ----
 
- ====
 
- === Publish a `WebSecurityCustomizer` Bean
 
- Spring Security 5.4 https://github.com/spring-projects/spring-security/issues/8978[introduced `WebSecurityCustomizer`] to replace `configure(WebSecurity web)` in `WebSecurityConfigurerAdapter`.
 
- To prepare for its removal, you can replace code like the following:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-     @Override
 
-     public void configure(WebSecurity web) {
 
-         web.ignoring().antMatchers("/ignore1", "/ignore2");
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
 
-     override fun configure(val web: WebSecurity) {
 
-         web.ignoring().antMatchers("/ignore1", "/ignore2")
 
-     }
 
- }
 
- ----
 
- ====
 
- with:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration {
 
-     @Bean
 
-     public WebSecurityCustomizer webSecurityCustomizer() {
 
-         return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration {
 
-     @Bean
 
-     fun webSecurityCustomizer(): WebSecurityCustomizer {
 
-         return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2")
 
-     }
 
- }
 
- ----
 
- ====
 
- === Publish an `AuthenticationManager` Bean
 
- As part of `WebSecurityConfigurerAdapeter` removal, `configure(AuthenticationManagerBuilder)` is also removed.
 
- Preparing for its removal will differ based on your reason for using it.
 
- ==== LDAP Authentication
 
- If you are using `auth.ldapAuthentication()` for xref:servlet/authentication/passwords/ldap.adoc[LDAP authentication support], you can replace:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-     @Override
 
-     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
-         auth
 
-             .ldapAuthentication()
 
-                 .userDetailsContextMapper(new PersonContextMapper())
 
-                 .userDnPatterns("uid={0},ou=people")
 
-                 .contextSource()
 
-                 .port(0);
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
 
-     override fun configure(auth: AuthenticationManagerBuilder) {
 
-         auth
 
-             .ldapAuthentication()
 
-                 .userDetailsContextMapper(PersonContextMapper())
 
-                 .userDnPatterns("uid={0},ou=people")
 
-                 .contextSource()
 
-                 .port(0)
 
-     }
 
- }
 
- ----
 
- ====
 
- with:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration {
 
-     @Bean
 
-     public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
 
-         EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
 
-             EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
 
-         contextSourceFactoryBean.setPort(0);
 
-         return contextSourceFactoryBean;
 
-     }
 
-     @Bean
 
-     AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
 
-         LdapBindAuthenticationManagerFactory factory =
 
-             new LdapBindAuthenticationManagerFactory(contextSource);
 
-         factory.setUserDnPatterns("uid={0},ou=people");
 
-         factory.setUserDetailsContextMapper(new PersonContextMapper());
 
-         return factory.createAuthenticationManager();
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration {
 
-     @Bean
 
-     fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
 
-         val contextSourceFactoryBean: EmbeddedLdapServerContextSourceFactoryBean =
 
-             EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
 
-         contextSourceFactoryBean.setPort(0)
 
-         return contextSourceFactoryBean
 
-     }
 
-     @Bean
 
-     fun ldapAuthenticationManager(val contextSource: BaseLdapPathContextSource): AuthenticationManager {
 
-         val factory = LdapBindAuthenticationManagerFactory(contextSource)
 
-         factory.setUserDnPatterns("uid={0},ou=people")
 
-         factory.setUserDetailsContextMapper(PersonContextMapper())
 
-         return factory.createAuthenticationManager()
 
-     }
 
- }
 
- ----
 
- ====
 
- ==== JDBC Authentication
 
- If you are using `auth.jdbcAuthentication()` for xref:servlet/authentication/passwords/jdbc.adoc[JDBC Authentication support], you can replace:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-     @Bean
 
-     public DataSource dataSource() {
 
-         return new EmbeddedDatabaseBuilder()
 
-             .setType(EmbeddedDatabaseType.H2)
 
-             .build();
 
-     }
 
-     @Override
 
-     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build();
 
-         auth.jdbcAuthentication()
 
-             .withDefaultSchema()
 
-                 .dataSource(this.dataSource)
 
-                 .withUser(user);
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
 
-     @Bean
 
-     fun dataSource(): DataSource {
 
-         return EmbeddedDatabaseBuilder()
 
-             .setType(EmbeddedDatabaseType.H2)
 
-             .build()
 
-     }
 
-     override fun configure(val auth: AuthenticationManagerBuilder) {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build()
 
-         auth.jdbcAuthentication()
 
-             .withDefaultSchema()
 
-                 .dataSource(this.dataSource)
 
-                 .withUser(user)
 
-     }
 
- }
 
- ----
 
- ====
 
- with:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration {
 
-     @Bean
 
-     public DataSource dataSource() {
 
-         return new EmbeddedDatabaseBuilder()
 
-             .setType(EmbeddedDatabaseType.H2)
 
-             .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
 
-             .build();
 
-     }
 
-     @Bean
 
-     public UserDetailsManager users(DataSource dataSource) {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build();
 
-         JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
 
-         users.createUser(user);
 
-         return users;
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration {
 
-     @Bean
 
-     fun dataSource(): DataSource {
 
-         return EmbeddedDatabaseBuilder()
 
-             .setType(EmbeddedDatabaseType.H2)
 
-             .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
 
-             .build()
 
-     }
 
-     @Bean
 
-     fun users(val dataSource: DataSource): UserDetailsManager {
 
-         val user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build()
 
-         val users = JdbcUserDetailsManager(dataSource)
 
-         users.createUser(user)
 
-         return users
 
-     }
 
- }
 
- ----
 
- ====
 
- ==== In-Memory Authentication
 
- If you are using `auth.inMemoryAuthentication()` for xref:servlet/authentication/passwords/in-memory.adoc[In-Memory Authentication support], you can replace:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-     @Override
 
-     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build();
 
-         auth.inMemoryAuthentication()
 
-             .withUser(user);
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
 
-     override fun configure(val auth: AuthenticationManagerBuilder) {
 
-         val user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build()
 
-         auth.inMemoryAuthentication()
 
-             .withUser(user)
 
-     }
 
- }
 
- ----
 
- ====
 
- with:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- public class SecurityConfiguration {
 
-     @Bean
 
-     public InMemoryUserDetailsManager userDetailsService() {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build();
 
-         return new InMemoryUserDetailsManager(user);
 
-     }
 
- }
 
- ----
 
- .Kotlin
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Configuration
 
- open class SecurityConfiguration {
 
-     @Bean
 
-     fun userDetailsService(): InMemoryUserDetailsManager {
 
-         UserDetails user = User.withDefaultPasswordEncoder()
 
-             .username("user")
 
-             .password("password")
 
-             .roles("USER")
 
-             .build()
 
-         return InMemoryUserDetailsManager(user)
 
-     }
 
- }
 
- ----
 
- ====
 
- == Add `@Configuration` to `@Enable*` annotations
 
- In 6.0, all Spring Security's `@Enable*` annotations had their `@Configuration` removed.
 
- While convenient, it was not consistent with the rest of the Spring projects and most notably Spring Framework's `@Enable*` annotations.
 
- Additionally, the introduction of support for `@Configuration(proxyBeanMethods=false)` in Spring Framework provides another reason to remove `@Configuration` meta-annotation from Spring Security's `@Enable*` annotations and allow users to opt into their preferred configuration mode.
 
- The following annotations had their `@Configuration` removed:
 
- - `@EnableGlobalAuthentication`
 
- - `@EnableGlobalMethodSecurity`
 
- - `@EnableMethodSecurity`
 
- - `@EnableReactiveMethodSecurity`
 
- - `@EnableWebSecurity`
 
- - `@EnableWebFluxSecurity`
 
- For example, if you are using `@EnableWebSecurity`, you will need to change:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @EnableWebSecurity
 
- public class SecurityConfig {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- to:
 
- ====
 
- .Java
 
- [source,java,role="primary"]
 
- ----
 
- @Configuration
 
- @EnableWebSecurity
 
- public class SecurityConfig {
 
- 	// ...
 
- }
 
- ----
 
- ====
 
- And the same applies to every other annotation listed above.
 
- === Other Scenarios
 
- If you are using `AuthenticationManagerBuilder` for something more sophisticated, you can xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationmanager[publish your own `AuthenticationManager` `@Bean`] or wire an `AuthenticationManager` instance into the `HttpSecurity` DSL with {security-api-url}org/springframework/security/config/annotation/web/builders/HttpSecurity.html#authenticationManager(org.springframework.security.authentication.AuthenticationManager)[`HttpSecurity#authenticationManager`].
 
 
  |