| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 | = Configuration MigrationsThe following steps relate to changes around how to configure `HttpSecurity`, `WebSecurity`, and `AuthenticationManager`.[[add-configuration-annotation]]== Add `@Configuration` annotationIn 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"]----@EnableMethodSecuritypublic class MyConfiguration {	// ...}----.Kotlin[source,java,role="primary"]----@EnableMethodSecurityopen class MyConfiguration {	// ...}----====to:====.Java[source,java,role="primary"]----@Configuration@EnableMethodSecuritypublic class MyConfiguration {	// ...}----.Kotlin[source,java,role="primary"]----@Configuration@EnableMethodSecurityopen class MyConfiguration {	// ...}----====[[use-new-requestmatchers]]== Use the new `requestMatchers` methodsIn 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@EnableWebSecuritypublic 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@EnableWebSecuritypublic 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@EnableWebMvcpublic 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@EnableWebMvcpublic 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@EnableWebMvcpublic 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@EnableWebMvcpublic 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@EnableWebSecuritypublic 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"]----@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {	return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");}----====with their `requestMatchers` counterparts:====.Java[source,java,role="primary"]----@Beanpublic 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"]----@Beanpublic 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"]----@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {    http        .csrf((csrf) -> csrf            .ignoringRequestMatchers("/no-csrf")        );    return http.build();}----====[[use-new-security-matchers]]== Use the new `securityMatchers` methodsIn 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"]----@Beanpublic 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"]----@Beanpublic 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"]----@Beanpublic 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"]----@Beanpublic 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"]----@Beanpublic 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"]----@Beanpublic 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;@Beanpublic 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` BeanSpring 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"]----@Configurationpublic 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"]----@Configurationopen class SecurityConfiguration: WebSecurityConfigurerAdapter() {    @Override    override fun configure(val http: HttpSecurity) {        http {            authorizeHttpRequests {                authorize(anyRequest, authenticated)            }            httpBasic {}        }    }}----====with:====.Java[source,java,role="primary"]----@Configurationpublic 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"]----@Configurationopen class SecurityConfiguration {    @Bean    fun filterChain(http: HttpSecurity): SecurityFilterChain {        http {            authorizeHttpRequests {                authorize(anyRequest, authenticated)            }            httpBasic {}        }        return http.build()    }}----======= Publish a `WebSecurityCustomizer` BeanSpring 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"]----@Configurationpublic class SecurityConfiguration extends WebSecurityConfigurerAdapter {    @Override    public void configure(WebSecurity web) {        web.ignoring().antMatchers("/ignore1", "/ignore2");    }}----.Kotlin[source,kotlin,role="secondary"]----@Configurationopen class SecurityConfiguration: WebSecurityConfigurerAdapter() {    override fun configure(val web: WebSecurity) {        web.ignoring().antMatchers("/ignore1", "/ignore2")    }}----====with:====.Java[source,java,role="primary"]----@Configurationpublic class SecurityConfiguration {    @Bean    public WebSecurityCustomizer webSecurityCustomizer() {        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");    }}----.Kotlin[source,kotlin,role="secondary"]----@Configurationopen class SecurityConfiguration {    @Bean    fun webSecurityCustomizer(): WebSecurityCustomizer {        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2")    }}----======= Publish an `AuthenticationManager` BeanAs part of `WebSecurityConfigurerAdapeter` removal, `configure(AuthenticationManagerBuilder)` is also removed.Preparing for its removal will differ based on your reason for using it.==== LDAP AuthenticationIf you are using `auth.ldapAuthentication()` for xref:servlet/authentication/passwords/ldap.adoc[LDAP authentication support], you can replace:====.Java[source,java,role="primary"]----@Configurationpublic 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"]----@Configurationopen 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"]----@Configurationpublic 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"]----@Configurationopen 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 AuthenticationIf you are using `auth.jdbcAuthentication()` for xref:servlet/authentication/passwords/jdbc.adoc[JDBC Authentication support], you can replace:====.Java[source,java,role="primary"]----@Configurationpublic 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"]----@Configurationopen 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"]----@Configurationpublic 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"]----@Configurationopen 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 AuthenticationIf 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"]----@Configurationpublic 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"]----@Configurationopen 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"]----@Configurationpublic 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"]----@Configurationopen class SecurityConfiguration {    @Bean    fun userDetailsService(): InMemoryUserDetailsManager {        UserDetails user = User.withDefaultPasswordEncoder()            .username("user")            .password("password")            .roles("USER")            .build()        return InMemoryUserDetailsManager(user)    }}----====== Add `@Configuration` to `@Enable*` annotationsIn 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"]----@EnableWebSecuritypublic class SecurityConfig {	// ...}----====to:====.Java[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic class SecurityConfig {	// ...}----====And the same applies to every other annotation listed above.=== Other ScenariosIf 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`].
 |