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`].
|