You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1056 lines
27 KiB
1056 lines
27 KiB
= 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: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,role="primary"] |
|
---- |
|
@EnableMethodSecurity |
|
public class MyConfiguration { |
|
// ... |
|
} |
|
---- |
|
====== |
|
|
|
[tabs] |
|
====== |
|
Kotlin:: |
|
+ |
|
[source,java,role="primary"] |
|
---- |
|
@EnableMethodSecurity |
|
open class MyConfiguration { |
|
// ... |
|
} |
|
---- |
|
====== |
|
|
|
to: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,role="primary"] |
|
---- |
|
@Configuration |
|
@EnableMethodSecurity |
|
public class MyConfiguration { |
|
// ... |
|
} |
|
---- |
|
====== |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,role="primary"] |
|
---- |
|
@Bean |
|
public WebSecurityCustomizer webSecurityCustomizer() { |
|
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2"); |
|
} |
|
---- |
|
====== |
|
|
|
with their `requestMatchers` counterparts: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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`: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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`: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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 `WebSecurityConfigurerAdapter` 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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
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: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,role="primary"] |
|
---- |
|
@EnableWebSecurity |
|
public class SecurityConfig { |
|
// ... |
|
} |
|
---- |
|
====== |
|
|
|
to: |
|
|
|
[tabs] |
|
====== |
|
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`].
|
|
|