瀏覽代碼

Replace WebSecurityConfigurerAdapter with SecurityFilterChain in docs

Closes gh-10003
Eleftheria Stein 3 年之前
父節點
當前提交
4492e5b667
共有 22 個文件被更改,包括 622 次插入443 次删除
  1. 4 4
      docs/modules/ROOT/pages/servlet/authentication/logout.adoc
  2. 6 2
      docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc
  3. 4 2
      docs/modules/ROOT/pages/servlet/authentication/passwords/digest.adoc
  4. 8 8
      docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc
  5. 12 8
      docs/modules/ROOT/pages/servlet/authentication/session-management.adoc
  6. 12 4
      docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc
  7. 38 37
      docs/modules/ROOT/pages/servlet/configuration/java.adoc
  8. 24 24
      docs/modules/ROOT/pages/servlet/configuration/kotlin.adoc
  9. 24 18
      docs/modules/ROOT/pages/servlet/exploits/csrf.adoc
  10. 144 108
      docs/modules/ROOT/pages/servlet/exploits/headers.adoc
  11. 8 6
      docs/modules/ROOT/pages/servlet/exploits/http.adoc
  12. 16 10
      docs/modules/ROOT/pages/servlet/integrations/cors.adoc
  13. 12 4
      docs/modules/ROOT/pages/servlet/integrations/mvc.adoc
  14. 14 12
      docs/modules/ROOT/pages/servlet/integrations/websocket.adoc
  15. 24 15
      docs/modules/ROOT/pages/servlet/oauth2/client/authorization-grants.adoc
  16. 8 5
      docs/modules/ROOT/pages/servlet/oauth2/client/index.adoc
  17. 80 50
      docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc
  18. 45 52
      docs/modules/ROOT/pages/servlet/oauth2/login/core.adoc
  19. 48 24
      docs/modules/ROOT/pages/servlet/oauth2/resource-server/jwt.adoc
  20. 41 21
      docs/modules/ROOT/pages/servlet/oauth2/resource-server/opaque-token.adoc
  21. 24 15
      docs/modules/ROOT/pages/servlet/saml2/login/authentication.adoc
  22. 26 14
      docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc

+ 4 - 4
docs/modules/ROOT/pages/servlet/authentication/logout.adoc

@@ -4,7 +4,7 @@
 [[logout-java-configuration]]
 == Logout Java/Kotlin Configuration
 
-When using the `{security-api-url}org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[WebSecurityConfigurerAdapter]`, logout capabilities are automatically applied.
+When injecting the `{security-api-url}org/springframework/security/config/annotation/web/builders/HttpSecurity.html[HttpSecurity]` bean, logout capabilities are automatically applied.
 The default is that accessing the URL `/logout` will log the user out by:
 
 - Invalidating the HTTP Session
@@ -19,7 +19,7 @@ Similar to configuring login capabilities, however, you also have various option
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) throws Exception {
+public SecurityFilterChain filterChain(HttpSecurity http) {
     http
         .logout(logout -> logout                                                // <1>
             .logoutUrl("/my/logout")                                            // <2>
@@ -36,7 +36,7 @@ protected void configure(HttpSecurity http) throws Exception {
 .Kotlin
 [source,kotlin,role="secondary"]
 -----
-override fun configure(http: HttpSecurity) {
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         logout {
             logoutUrl = "/my/logout"                              // <1>
@@ -47,12 +47,12 @@ override fun configure(http: HttpSecurity) {
             deleteCookies(cookieNamesToClear)                     // <6>
         }
     }
+    // ...
 }
 -----
 ====
 
 <1> Provides logout support.
-This is automatically applied when using `WebSecurityConfigurerAdapter`.
 <2> The URL that triggers log out to occur (default is `/logout`).
 If CSRF protection is enabled (default), then the request must also be a POST.
 For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutUrl-java.lang.String-[Javadoc].

+ 6 - 2
docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc

@@ -62,10 +62,12 @@ A minimal, explicit configuration can be found below:
 [source,java,role="primary"]
 .Java
 ----
-protected void configure(HttpSecurity http) {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) {
 	http
 		// ...
 		.httpBasic(withDefaults());
+	return http.build();
 }
 ----
 
@@ -81,11 +83,13 @@ protected void configure(HttpSecurity http) {
 [source,kotlin,role="secondary"]
 .Kotlin
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 	http {
 		// ...
 		httpBasic { }
 	}
+	return http.build()
 }
 ----
 ====

+ 4 - 2
docs/modules/ROOT/pages/servlet/authentication/passwords/digest.adoc

@@ -1,4 +1,4 @@
-[[servlet-authentication-digest]]
+**[[**servlet-authentication-digest]]
 = Digest Authentication
 
 This section provides details on how Spring Security provides support for https://tools.ietf.org/html/rfc2617[Digest Authentication] which is provided `DigestAuthenticationFilter`.
@@ -57,11 +57,13 @@ DigestAuthenticationFilter digestAuthenticationFilter() {
 	result.setAuthenticationEntryPoint(entryPoint());
 }
 
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		// ...
 		.exceptionHandling(e -> e.authenticationEntryPoint(authenticationEntryPoint()))
 		.addFilterBefore(digestFilter());
+	return http.build();
 }
 ----
 

+ 8 - 8
docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc

@@ -71,10 +71,10 @@ A minimal, explicit Java configuration can be found below:
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) {
+public SecurityFilterChain filterChain(HttpSecurity http) {
 	http
-		// ...
 		.formLogin(withDefaults());
+	// ...
 }
 ----
 
@@ -90,11 +90,11 @@ protected void configure(HttpSecurity http) {
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 	http {
-		// ...
 		formLogin { }
 	}
+	// ...
 }
 ----
 ====
@@ -110,13 +110,13 @@ The configuration below demonstrates how to provide a custom log in form.
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) throws Exception {
+public SecurityFilterChain filterChain(HttpSecurity http) {
 	http
-		// ...
 		.formLogin(form -> form
 			.loginPage("/login")
 			.permitAll()
 		);
+	// ...
 }
 ----
 
@@ -133,14 +133,14 @@ protected void configure(HttpSecurity http) throws Exception {
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 	http {
-		// ...
 		formLogin {
 			loginPage = "/login"
 			permitAll()
 		}
 	}
+	// ...
 }
 ----
 ====

+ 12 - 8
docs/modules/ROOT/pages/servlet/authentication/session-management.adoc

@@ -11,12 +11,13 @@ This is achieved through the `session-management` element:
 .Java
 [source,java,role="primary"]
 ----
-@Override
-protected void configure(HttpSecurity http) throws Exception{
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) {
     http
         .sessionManagement(session -> session
             .invalidSessionUrl("/invalidSession.htm")
         );
+    return http.build();
 }
 ----
 
@@ -38,12 +39,13 @@ You may be able to explicitly delete the JSESSIONID cookie on logging out, for e
 .Java
 [source,java,role="primary"]
 ----
-@Override
-protected void configure(HttpSecurity http) throws Exception{
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) {
     http
         .logout(logout -> logout
             .deleteCookies("JSESSIONID")
         );
+    return http.build();
 }
 ----
 
@@ -105,12 +107,13 @@ Then add the following lines to your application context:
 .Java
 [source,java,role="primary"]
 ----
-@Override
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) {
     http
         .sessionManagement(session -> session
             .maximumSessions(1)
         );
+    return http.build();
 }
 ----
 
@@ -134,13 +137,14 @@ Often you would prefer to prevent a second login, in which case you can use
 .Java
 [source,java,role="primary"]
 ----
-@Override
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) {
     http
         .sessionManagement(session -> session
             .maximumSessions(1)
             .maxSessionsPreventsLogin(true)
         );
+    return http.build();
 }
 ----
 

+ 12 - 4
docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc

@@ -34,12 +34,14 @@ The explicit configuration looks like:
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		// ...
 		.authorizeRequests(authorize -> authorize
 			.anyRequest().authenticated()
 		);
+	return http.build();
 }
 ----
 
@@ -55,13 +57,15 @@ protected void configure(HttpSecurity http) throws Exception {
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         // ...
         authorizeRequests {
             authorize(anyRequest, authenticated)
         }
     }
+    return http.build()
 }
 ----
 ====
@@ -73,7 +77,8 @@ We can configure Spring Security to have different rules by adding more rules in
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		// ...
 		.authorizeRequests(authorize -> authorize                                  // <1>
@@ -82,6 +87,7 @@ protected void configure(HttpSecurity http) throws Exception {
 			.mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")   // <4>
 			.anyRequest().denyAll()                                                // <5>
 		);
+	return http.build();
 }
 ----
 
@@ -104,7 +110,8 @@ protected void configure(HttpSecurity http) throws Exception {
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
    http {
         authorizeRequests { // <1>
             authorize("/resources/**", permitAll) // <2>
@@ -116,6 +123,7 @@ fun configure(http: HttpSecurity) {
             authorize(anyRequest, denyAll) // <5>
         }
     }
+    return http.build()
 }
 ----
 ====

+ 38 - 37
docs/modules/ROOT/pages/servlet/configuration/java.adoc

@@ -135,18 +135,20 @@ public class MvcWebApplicationInitializer extends
 Thus far our <<jc-hello-wsca,WebSecurityConfig>> only contains information about how to authenticate our users.
 How does Spring Security know that we want to require all users to be authenticated?
 How does Spring Security know we want to support form based authentication?
-Actually, there is a configuration class that is being invoked behind the scenes called `WebSecurityConfigurerAdapter`.
-It has a method called `configure` with the following default implementation:
+Actually, there is a bean that is being invoked behind the scenes called `SecurityFilterChain`.
+It is configured with the following default implementation:
 
 [source,java]
 ----
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		.authorizeRequests(authorize -> authorize
 			.anyRequest().authenticated()
 		)
 		.formLogin(withDefaults())
 		.httpBasic(withDefaults());
+	return http.build();
 }
 ----
 
@@ -170,7 +172,7 @@ You will notice that this configuration is quite similar the XML Namespace confi
 == Multiple HttpSecurity
 
 We can configure multiple HttpSecurity instances just as we can have multiple `<http>` blocks.
-The key is to extend the `WebSecurityConfigurerAdapter` multiple times.
+The key is to register multiple `SecurityFilterChain` `@Bean`s.
 For example, the following is an example of having a different configuration for URL's that start with `/api/`.
 
 [source,java]
@@ -187,40 +189,36 @@ public class MultiHttpSecurityConfig {
 		return manager;
 	}
 
-	@Configuration
+	@Bean
 	@Order(1)                                                        <2>
-	public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.antMatcher("/api/**")                               <3>
-				.authorizeHttpRequests(authorize -> authorize
-					.anyRequest().hasRole("ADMIN")
-			    )
-				.httpBasic(withDefaults());
-		}
+	public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
+		http
+			.antMatcher("/api/**")                                   <3>
+			.authorizeHttpRequests(authorize -> authorize
+				.anyRequest().hasRole("ADMIN")
+			)
+			.httpBasic(withDefaults());
+		return http.build();
 	}
 
-	@Configuration                                                   <4>
-	public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeHttpRequests(authorize -> authorize
-					.anyRequest().authenticated()
-				)
-				.formLogin(withDefaults());
-		}
+	@Bean                                                            <4>
+	public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
+		http
+			.authorizeHttpRequests(authorize -> authorize
+				.anyRequest().authenticated()
+			)
+			.formLogin(withDefaults());
+		return http.build();
 	}
 }
 ----
 
 <1> Configure Authentication as normal
-<2> Create an instance of `WebSecurityConfigurerAdapter` that contains `@Order` to specify which `WebSecurityConfigurerAdapter` should be considered first.
+<2> Register an instance of `SecurityFilterChain` that contains `@Order` to specify which `SecurityFilterChain` should be considered first.
 <3> The `http.antMatcher` states that this `HttpSecurity` will only be applicable to URLs that start with `/api/`
-<4> Create another instance of `WebSecurityConfigurerAdapter`.
+<4> Register another instance of `SecurityFilterChain`.
 If the URL does not start with `/api/` this configuration will be used.
-This configuration is considered after `ApiWebSecurityConfigurationAdapter` since it has an `@Order` value after `1` (no `@Order` defaults to last).
+This configuration is considered after `apiFilterChain` since it has an `@Order` value after `1` (no `@Order` defaults to last).
 
 [[jc-custom-dsls]]
 == Custom DSLs
@@ -268,14 +266,15 @@ The custom DSL can then be used like this:
 [source,java]
 ----
 @EnableWebSecurity
-public class Config extends WebSecurityConfigurerAdapter {
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+public class Config {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.apply(customDsl())
 				.flag(true)
 				.and()
 			...;
+		return http.build();
 	}
 }
 ----
@@ -286,7 +285,7 @@ The code is invoked in the following order:
 * Code in `MyCustomDsl`s init method is invoked
 * Code in `MyCustomDsl`s configure method is invoked
 
-If you want, you can have `WebSecurityConfigurerAdapter` add `MyCustomDsl` by default by using `SpringFactories`.
+If you want, you can add `MyCustomDsl` to `HttpSecurity` by default by using `SpringFactories`.
 For example, you would create a resource on the classpath named `META-INF/spring.factories` with the following contents:
 
 .META-INF/spring.factories
@@ -299,12 +298,13 @@ Users wishing to disable the default can do so explicitly.
 [source,java]
 ----
 @EnableWebSecurity
-public class Config extends WebSecurityConfigurerAdapter {
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+public class Config {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.apply(customDsl()).disable()
 			...;
+		return http.build();
 	}
 }
 ----
@@ -322,8 +322,8 @@ For example, if you wanted to configure the `filterSecurityPublishAuthorizationS
 
 [source,java]
 ----
-@Override
-protected void configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		.authorizeRequests(authorize -> authorize
 			.anyRequest().authenticated()
@@ -335,5 +335,6 @@ protected void configure(HttpSecurity http) throws Exception {
 				}
 			})
 		);
+	return http.build();
 }
 ----

+ 24 - 24
docs/modules/ROOT/pages/servlet/configuration/kotlin.adoc

@@ -11,12 +11,13 @@ NOTE: Spring Security provides https://github.com/spring-projects/spring-securit
 
 How does Spring Security know that we want to require all users to be authenticated?
 How does Spring Security know we want to support form based authentication?
-There is a configuration class that is being invoked behind the scenes called `WebSecurityConfigurerAdapter`.
-It has a method called `configure` with the following default implementation:
+Actually, there is a bean that is being invoked behind the scenes called `SecurityFilterChain`.
+It is configured with the following default implementation:
 
 [source,kotlin]
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
    http {
         authorizeRequests {
             authorize(anyRequest, authenticated)
@@ -24,6 +25,7 @@ fun configure(http: HttpSecurity) {
        formLogin { }
        httpBasic { }
     }
+    return http.build()
 }
 ----
 
@@ -47,7 +49,7 @@ You will notice that this configuration is quite similar the XML Namespace confi
 == Multiple HttpSecurity
 
 We can configure multiple HttpSecurity instances just as we can have multiple `<http>` blocks.
-The key is to extend the `WebSecurityConfigurerAdapter` multiple times.
+The key is to register multiple `SecurityFilterChain` `@Bean`s.
 For example, the following is an example of having a different configuration for URL's that start with `/api/`.
 
 [source,kotlin]
@@ -63,37 +65,35 @@ class MultiHttpSecurityConfig {
         return manager
     }
 
-    @Configuration
     @Order(1)                                                        <2>
-    class ApiWebSecurityConfigurationAdapter: WebSecurityConfigurerAdapter() {
-        override fun configure(http: HttpSecurity) {
-            http {
-                securityMatcher("/api/**")                           <3>
-                authorizeRequests {
-                    authorize(anyRequest, hasRole("ADMIN"))
-                }
-                httpBasic { }
+    @Bean
+    open fun apiFilterChain(http: HttpSecurity): SecurityFilterChain {
+        http {
+            securityMatcher("/api/**")                               <3>
+            authorizeRequests {
+                authorize(anyRequest, hasRole("ADMIN"))
             }
+            httpBasic { }
         }
+        return http.build()
     }
 
-    @Configuration                                                   <4>
-    class FormLoginWebSecurityConfigurerAdapter: WebSecurityConfigurerAdapter() {
-        override fun configure(http: HttpSecurity) {
-            http {
-                authorizeRequests {
-                    authorize(anyRequest, authenticated)
-                }
-                formLogin { }
+    @Bean                                                            <4>
+    open fun formLoginFilterChain(http: HttpSecurity): SecurityFilterChain {
+        http {
+            authorizeRequests {
+                authorize(anyRequest, authenticated)
             }
+            formLogin { }
         }
+        return http.build()
     }
 }
 ----
 
 <1> Configure Authentication as normal
-<2> Create an instance of `WebSecurityConfigurerAdapter` that contains `@Order` to specify which `WebSecurityConfigurerAdapter` should be considered first.
+<2> Expose an instance of `SecurityFilterChain` that contains `@Order` to specify which `SecurityFilterChain` should be considered first.
 <3> The `http.antMatcher` states that this `HttpSecurity` will only be applicable to URLs that start with `/api/`
-<4> Create another instance of `WebSecurityConfigurerAdapter`.
+<4> Expose another instance of `SecurityFilterChain`.
 If the URL does not start with `/api/` this configuration will be used.
-This configuration is considered after `ApiWebSecurityConfigurationAdapter` since it has an `@Order` value after `1` (no `@Order` defaults to last).
+This configuration is considered after `apiFilterChain` since it has an `@Order` value after `1` (no `@Order` defaults to last).

+ 24 - 18
docs/modules/ROOT/pages/servlet/exploits/csrf.adoc

@@ -65,15 +65,15 @@ You can configure `CookieCsrfTokenRepository` in Java Configuration using:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.csrf(csrf -> csrf
 				.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
 			);
+		return http.build();
 	}
 }
 ----
@@ -82,14 +82,16 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             csrf {
                 csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
             }
         }
+        return http.build()
     }
 }
 ----
@@ -130,13 +132,13 @@ The Java configuration below will disable CSRF protection.
 ----
 @Configuration
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.csrf(csrf -> csrf.disable());
+		return http.build();
 	}
 }
 ----
@@ -146,14 +148,16 @@ public class WebSecurityConfig extends
 ----
 @Configuration
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             csrf {
                 disable()
             }
         }
+        return http.build()
     }
 }
 ----
@@ -330,15 +334,15 @@ For example, the following Java Configuration will perform logout with the URL `
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.logout(logout -> logout
 				.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
 			);
+		return http.build();
 	}
 }
 ----
@@ -347,14 +351,16 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             logout {
                 logoutRequestMatcher = AntPathRequestMatcher("/logout")
             }
         }
+        return http.build()
     }
 }
 ----

+ 144 - 108
docs/modules/ROOT/pages/servlet/exploits/headers.adoc

@@ -21,11 +21,10 @@ You can easily do this with the following Configuration:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -33,6 +32,7 @@ public class WebSecurityConfig extends
 					.sameOrigin()
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -53,8 +53,9 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class SecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -63,6 +64,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -79,11 +81,10 @@ If you are using Spring Security's Configuration the following will only add xre
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -91,6 +92,7 @@ WebSecurityConfigurerAdapter {
 				.defaultsDisabled()
 				.cacheControl(withDefaults())
 			);
+		return http.build();
 	}
 }
 ----
@@ -111,8 +113,9 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class SecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -122,6 +125,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -135,14 +139,14 @@ If necessary, you can disable all of the HTTP Security response headers with the
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers.disable());
+		return http.build();
 	}
 }
 ----
@@ -161,14 +165,16 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class SecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
                 disable()
             }
         }
+        return http.build()
     }
 }
 ----
@@ -194,16 +200,16 @@ If necessary, you can also disable Spring Security's cache control HTTP response
 ----
 @Configuration
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
 				.cacheControl(cache -> cache.disable())
 			);
+		return http.build();
 	}
 }
 ----
@@ -224,9 +230,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             headers {
                 cacheControl {
@@ -234,6 +241,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -252,16 +260,16 @@ However, you can disable it with:
 ----
 @Configuration
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
 				.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
 			);
+		return http.build();
 	}
 }
 ----
@@ -282,9 +290,10 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             headers {
                 contentTypeOptions {
@@ -292,6 +301,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -310,11 +320,10 @@ For example, the following is an example of explicitly providing HSTS:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -324,6 +333,7 @@ WebSecurityConfigurerAdapter {
 					.maxAgeInSeconds(31536000)
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -347,9 +357,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             headers {
                 httpStrictTransportSecurity {
@@ -359,6 +370,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -376,11 +388,10 @@ You can enable HPKP headers with the following Configuration:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -390,6 +401,7 @@ WebSecurityConfigurerAdapter {
 					.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -416,9 +428,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             headers {
                 httpPublicKeyPinning {
@@ -429,6 +442,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -447,11 +461,10 @@ You can customize frame options to use the same origin within a Configuration us
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -459,6 +472,7 @@ WebSecurityConfigurerAdapter {
 					.sameOrigin()
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -481,9 +495,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             headers {
                 frameOptions {
@@ -491,6 +506,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -509,11 +525,10 @@ For example, the following Configuration specifies that Spring Security should n
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -521,6 +536,7 @@ WebSecurityConfigurerAdapter {
 					.block(false)
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -541,9 +557,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         // ...
         http {
             headers {
@@ -552,6 +569,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -581,11 +599,10 @@ You can enable the CSP header as shown below:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -593,6 +610,7 @@ WebSecurityConfigurerAdapter {
 					.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -614,9 +632,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -625,6 +644,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -638,11 +658,10 @@ To enable the CSP `report-only` header, provide the following configuration:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -651,6 +670,7 @@ public class WebSecurityConfig extends
 					.reportOnly()
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -673,9 +693,10 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -685,6 +706,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -702,11 +724,10 @@ You can enable the Referrer Policy header using the configuration as shown below
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -714,6 +735,7 @@ WebSecurityConfigurerAdapter {
 					.policy(ReferrerPolicy.SAME_ORIGIN)
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -734,9 +756,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -745,6 +768,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -772,16 +796,16 @@ can enable the Feature Policy header using the configuration shown below:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
 				.featurePolicy("geolocation 'self'")
 			);
+		return http.build();
 	}
 }
 ----
@@ -802,15 +826,17 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
                 featurePolicy("geolocation 'self'")
             }
         }
+        return http.build()
     }
 }
 ----
@@ -838,11 +864,10 @@ can enable the Permissions Policy header using the configuration shown below:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
@@ -850,6 +875,7 @@ WebSecurityConfigurerAdapter {
 					.policy("geolocation=(self)")
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -870,9 +896,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -881,6 +908,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -907,16 +935,16 @@ can be sent on log out with the following configuration:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.logout((logout) -> logout
                 .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)))
 			);
+		return http.build();
 	}
 }
 ----
@@ -925,15 +953,17 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             logout {
                 addLogoutHandler(HeaderWriterLogoutHandler(ClearSiteDataHeaderWriter(CACHE, COOKIES)))
             }
         }
+        return http.build()
     }
 }
 ----
@@ -1023,16 +1053,16 @@ The headers could be added to the response using the following Configuration:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
 				.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
 			);
+		return http.build();
 	}
 }
 ----
@@ -1053,15 +1083,17 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
                 addHeaderWriter(StaticHeadersWriter("X-Custom-Security-Header","header-value"))
             }
         }
+        return http.build()
     }
 }
 ----
@@ -1080,16 +1112,16 @@ If you wanted to explicitly configure <<servlet-headers-frame-options>> it could
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.headers(headers -> headers
 				.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
 			);
+		return http.build();
 	}
 }
 ----
@@ -1116,15 +1148,17 @@ See https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsi
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
                 addHeaderWriter(XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
             }
         }
+        return http.build()
     }
 }
 ----
@@ -1145,11 +1179,10 @@ An example of using `DelegatingRequestMatcherHeaderWriter` in Java Configuration
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		RequestMatcher matcher = new AntPathRequestMatcher("/login");
 		DelegatingRequestMatcherHeaderWriter headerWriter =
 			new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
@@ -1159,6 +1192,7 @@ WebSecurityConfigurerAdapter {
 				.frameOptions(frameOptions -> frameOptions.disable())
 				.addHeaderWriter(headerWriter)
 			);
+		return http.build();
 	}
 }
 ----
@@ -1192,9 +1226,10 @@ WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         val matcher: RequestMatcher = AntPathRequestMatcher("/login")
         val headerWriter = DelegatingRequestMatcherHeaderWriter(matcher, XFrameOptionsHeaderWriter())
        http {
@@ -1205,6 +1240,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 addHeaderWriter(headerWriter)
             }
         }
+        return http.build()
     }
 }
 ----

+ 8 - 6
docs/modules/ROOT/pages/servlet/exploits/http.adoc

@@ -19,16 +19,16 @@ For example, the following Java configuration will redirect any HTTP requests to
 ----
 @Configuration
 @EnableWebSecurity
-public class WebSecurityConfig extends
-		WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// ...
 			.requiresChannel(channel -> channel
 				.anyRequest().requiresSecure()
 			);
+		return http.build();
 	}
 }
 ----
@@ -38,15 +38,17 @@ public class WebSecurityConfig extends
 ----
 @Configuration
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             requiresChannel {
                 secure(AnyRequestMatcher.INSTANCE, "REQUIRES_SECURE_CHANNEL")
             }
         }
+        return http.build()
     }
 }
 ----

+ 16 - 10
docs/modules/ROOT/pages/servlet/integrations/cors.adoc

@@ -13,14 +13,15 @@ Users can integrate the `CorsFilter` with Spring Security by providing a `CorsCo
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// by default uses a Bean by the name of corsConfigurationSource
 			.cors(withDefaults())
 			...
+		return http.build();
 	}
 
 	@Bean
@@ -39,13 +40,15 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class WebSecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // by default uses a Bean by the name of corsConfigurationSource
             cors { }
             // ...
         }
+        return http.build()
     }
 
     @Bean
@@ -81,15 +84,16 @@ If you are using Spring MVC's CORS support, you can omit specifying the `CorsCon
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			// if Spring MVC is on classpath and no CorsConfigurationSource is provided,
 			// Spring Security will use CORS configuration provided to Spring MVC
 			.cors(withDefaults())
 			...
+		return http.build();
 	}
 }
 ----
@@ -98,14 +102,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class WebSecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // if Spring MVC is on classpath and no CorsConfigurationSource is provided,
             // Spring Security will use CORS configuration provided to Spring MVC
             cors { }
             // ...
         }
+        return http.build()
     }
 }
 ----

+ 12 - 4
docs/modules/ROOT/pages/servlet/integrations/mvc.adoc

@@ -136,23 +136,27 @@ If we wanted to restrict access to this controller method to admin users, a deve
 .Java
 [source,java,role="primary"]
 ----
-protected configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		.authorizeHttpRequests(authorize -> authorize
 			.antMatchers("/admin").hasRole("ADMIN")
 		);
+	return http.build();
 }
 ----
 
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-override fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         authorizeRequests {
             authorize(AntPathRequestMatcher("/admin"), hasRole("ADMIN"))
         }
     }
+    return http.build()
 }
 ----
 ====
@@ -181,23 +185,27 @@ The following configuration will protect the same URLs that Spring MVC will matc
 .Java
 [source,java,role="primary"]
 ----
-protected configure(HttpSecurity http) throws Exception {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	http
 		.authorizeHttpRequests(authorize -> authorize
 			.mvcMatchers("/admin").hasRole("ADMIN")
 		);
+	// ...
 }
 ----
 
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-override fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         authorizeRequests {
             authorize("/admin", hasRole("ADMIN"))
         }
     }
+    // ...
 }
 ----
 ====

+ 14 - 12
docs/modules/ROOT/pages/servlet/integrations/websocket.adoc

@@ -382,11 +382,10 @@ Similarly, you can customize frame options to use the same origin within Java Co
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class WebSecurityConfig extends
-   WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             // ...
             .headers(headers -> headers
@@ -394,6 +393,7 @@ public class WebSecurityConfig extends
                      .sameOrigin()
                 )
         );
+        return http.build();
     }
 }
 ----
@@ -402,8 +402,9 @@ public class WebSecurityConfig extends
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class WebSecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             // ...
             headers {
@@ -412,6 +413,7 @@ open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -440,11 +442,10 @@ For example, if our stomp endpoint is "/chat" we can disable CSRF protection for
 ----
 @Configuration
 @EnableWebSecurity
-public class WebSecurityConfig
-    extends WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .csrf(csrf -> csrf
                 // ignore our stomp endpoints since they are protected using Stomp headers
@@ -467,8 +468,9 @@ public class WebSecurityConfig
 ----
 @Configuration
 @EnableWebSecurity
-open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class WebSecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             csrf {
                 ignoringAntMatchers("/chat/**")

+ 24 - 15
docs/modules/ROOT/pages/servlet/oauth2/client/authorization-grants.adoc

@@ -113,13 +113,13 @@ The following example shows how to configure the `DefaultOAuth2AuthorizationRequ
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
 	@Autowired
 	private ClientRegistrationRepository clientRegistrationRepository;
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.authorizeHttpRequests(authorize -> authorize
 				.anyRequest().authenticated()
@@ -131,6 +131,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 					)
 				)
 			);
+		return http.build();
 	}
 
 	private OAuth2AuthorizationRequestResolver authorizationRequestResolver(
@@ -156,12 +157,13 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class SecurityConfig : WebSecurityConfigurerAdapter() {
+class SecurityConfig {
 
     @Autowired
     private lateinit var customClientRegistrationRepository: ClientRegistrationRepository
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -172,6 +174,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 
     private fun authorizationRequestResolver(
@@ -260,10 +263,10 @@ If you have a custom implementation of `AuthorizationRequestRepository`, you may
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2ClientSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Client(oauth2 -> oauth2
 				.authorizationCodeGrant(codeGrant -> codeGrant
@@ -271,6 +274,7 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 					...
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -279,9 +283,10 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2ClientSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Client {
                 authorizationCodeGrant {
@@ -289,6 +294,7 @@ class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -371,10 +377,10 @@ Whether you customize `DefaultAuthorizationCodeTokenResponseClient` or provide y
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2ClientSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Client(oauth2 -> oauth2
 				.authorizationCodeGrant(codeGrant -> codeGrant
@@ -382,6 +388,7 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 					...
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -390,9 +397,10 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2ClientSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Client {
                 authorizationCodeGrant {
@@ -400,6 +408,7 @@ class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----

+ 8 - 5
docs/modules/ROOT/pages/servlet/oauth2/client/index.adoc

@@ -30,10 +30,10 @@ The following code shows the complete configuration options provided by the `Htt
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2ClientSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Client(oauth2 -> oauth2
 				.clientRegistrationRepository(this.clientRegistrationRepository())
@@ -45,6 +45,7 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 					.accessTokenResponseClient(this.accessTokenResponseClient())
 				)
 			);
+		return http.build();
 	}
 }
 ----
@@ -53,9 +54,10 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2ClientSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Client {
                 clientRegistrationRepository = clientRegistrationRepository()
@@ -68,6 +70,7 @@ class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----

+ 80 - 50
docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc

@@ -14,10 +14,10 @@ The following code shows an example:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .authorizationEndpoint(authorization -> authorization
@@ -33,6 +33,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			            ...
 			    )
 			);
+		return http.build();
 	}
 }
 ----
@@ -41,9 +42,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 authorizationEndpoint {
@@ -60,6 +62,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -92,10 +95,10 @@ The following code shows the complete configuration options available for the `o
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .clientRegistrationRepository(this.clientRegistrationRepository())
@@ -119,6 +122,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        .oidcUserService(this.oidcUserService())
 			    )
 			);
+		return http.build();
 	}
 }
 ----
@@ -127,9 +131,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 clientRegistrationRepository = clientRegistrationRepository()
@@ -154,6 +159,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -226,10 +232,10 @@ The following listing shows an example:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .loginPage("/login/oauth2")
@@ -239,6 +245,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        ...
 			    )
 			);
+		return http.build();
 	}
 }
 ----
@@ -247,9 +254,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 loginPage = "/login/oauth2"
@@ -258,6 +266,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -309,10 +318,10 @@ If you would like to customize the Authorization Response `baseUri`, configure i
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .redirectionEndpoint(redirection -> redirection
@@ -320,6 +329,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        ...
 			    )
 			);
+		return http.build();
 	}
 }
 ----
@@ -328,9 +338,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 redirectionEndpoint {
@@ -338,6 +349,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -416,10 +428,10 @@ Provide an implementation of `GrantedAuthoritiesMapper` and configure it as show
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .userInfoEndpoint(userInfo -> userInfo
@@ -427,6 +439,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        ...
 			    )
 			);
+		return http.build();
 	}
 
 	private GrantedAuthoritiesMapper userAuthoritiesMapper() {
@@ -464,9 +477,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 userInfoEndpoint {
@@ -474,6 +488,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 
     private fun userAuthoritiesMapper(): GrantedAuthoritiesMapper = GrantedAuthoritiesMapper { authorities: Collection<GrantedAuthority> ->
@@ -516,12 +531,13 @@ Alternatively, you may register a `GrantedAuthoritiesMapper` `@Bean` to have it
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 		    .oauth2Login(withDefaults());
+		return http.build();
 	}
 
 	@Bean
@@ -535,12 +551,14 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login { }
         }
+        return http.build()
     }
 
     @Bean
@@ -566,10 +584,10 @@ The following example shows how to implement and configure a delegation-based st
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .userInfoEndpoint(userInfo -> userInfo
@@ -577,6 +595,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        ...
 			    )
 			);
+		return http.build();
 	}
 
 	private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
@@ -606,9 +625,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig  {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 userInfoEndpoint {
@@ -616,6 +636,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 
     @Bean
@@ -685,10 +706,10 @@ Whether you customize `DefaultOAuth2UserService` or provide your own implementat
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 			    .userInfoEndpoint(userInfo -> userInfo
@@ -696,6 +717,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			        ...
 			    )
 			);
+		return http.build();
 	}
 
 	private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
@@ -708,9 +730,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 userInfoEndpoint {
@@ -719,6 +742,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 
     private fun oauth2UserService(): OAuth2UserService<OAuth2UserRequest, OAuth2User> {
@@ -745,10 +769,10 @@ Whether you customize `OidcUserService` or provide your own implementation of `O
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.oauth2Login(oauth2 -> oauth2
 				.userInfoEndpoint(userInfo -> userInfo
@@ -756,6 +780,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 				    ...
 			    )
 			);
+		return http.build();
 	}
 
 	private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
@@ -768,9 +793,10 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             oauth2Login {
                 userInfoEndpoint {
@@ -779,6 +805,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 
     private fun oidcUserService(): OAuth2UserService<OidcUserRequest, OidcUser> {
@@ -866,13 +893,13 @@ spring:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
 	@Autowired
 	private ClientRegistrationRepository clientRegistrationRepository;
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.authorizeHttpRequests(authorize -> authorize
 				.anyRequest().authenticated()
@@ -881,6 +908,7 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 			.logout(logout -> logout
 				.logoutSuccessHandler(oidcLogoutSuccessHandler())
 			);
+		return http.build();
 	}
 
 	private LogoutSuccessHandler oidcLogoutSuccessHandler() {
@@ -900,11 +928,12 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
     @Autowired
     private lateinit var clientRegistrationRepository: ClientRegistrationRepository
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -914,6 +943,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
                 logoutSuccessHandler = oidcLogoutSuccessHandler()
             }
         }
+        return http.build()
     }
 
     private fun oidcLogoutSuccessHandler(): LogoutSuccessHandler {

+ 45 - 52
docs/modules/ROOT/pages/servlet/oauth2/login/core.adoc

@@ -229,12 +229,12 @@ The Spring Boot 2.x auto-configuration class for OAuth Client support is `OAuth2
 It performs the following tasks:
 
 * Registers a `ClientRegistrationRepository` `@Bean` composed of `ClientRegistration`(s) from the configured OAuth Client properties.
-* Provides a `WebSecurityConfigurerAdapter` `@Configuration` and enables OAuth 2.0 Login through `httpSecurity.oauth2Login()`.
+* Registers a `SecurityFilterChain` `@Bean` and enables OAuth 2.0 Login through `httpSecurity.oauth2Login()`.
 
 If you need to override the auto-configuration based on your specific requirements, you may do so in the following ways:
 
 * <<oauth2login-register-clientregistrationrepository-bean,Register a ClientRegistrationRepository @Bean>>
-* <<oauth2login-provide-websecurityconfigureradapter,Provide a WebSecurityConfigurerAdapter>>
+* <<oauth2login-provide-securityfilterchain-bean,Register a SecurityFilterChain @Bean>>
 * <<oauth2login-completely-override-autoconfiguration,Completely Override the Auto-configuration>>
 
 
@@ -305,10 +305,10 @@ class OAuth2LoginConfig {
 ====
 
 
-[[oauth2login-provide-websecurityconfigureradapter]]
-=== Provide a WebSecurityConfigurerAdapter
+[[oauth2login-provide-securityfilterchain-bean]]
+=== Register a SecurityFilterChain @Bean
 
-The following example shows how to provide a `WebSecurityConfigurerAdapter` with `@EnableWebSecurity` and enable OAuth 2.0 login through `httpSecurity.oauth2Login()`:
+The following example shows how to register a `SecurityFilterChain` `@Bean` with `@EnableWebSecurity` and enable OAuth 2.0 login through `httpSecurity.oauth2Login()`:
 
 .OAuth2 Login Configuration
 ====
@@ -316,15 +316,16 @@ The following example shows how to provide a `WebSecurityConfigurerAdapter` with
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
+public class OAuth2LoginSecurityConfig {
 
-	@Override
-	protected void configure(HttpSecurity http) throws Exception {
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 		http
 			.authorizeHttpRequests(authorize -> authorize
 				.anyRequest().authenticated()
 			)
 			.oauth2Login(withDefaults());
+		return http.build();
 	}
 }
 ----
@@ -333,15 +334,16 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
+class OAuth2LoginSecurityConfig {
 
-    override fun configure(http: HttpSecurity) {
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
             }
             oauth2Login { }
         }
+        return http.build()
     }
 }
 ----
@@ -351,7 +353,7 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
 [[oauth2login-completely-override-autoconfiguration]]
 === Completely Override the Auto-configuration
 
-The following example shows how to completely override the auto-configuration by registering a `ClientRegistrationRepository` `@Bean` and providing a `WebSecurityConfigurerAdapter`.
+The following example shows how to completely override the auto-configuration by registering a `ClientRegistrationRepository` `@Bean` and a `SecurityFilterChain` `@Bean`.
 
 .Overriding the auto-configuration
 ====
@@ -361,17 +363,14 @@ The following example shows how to completely override the auto-configuration by
 @Configuration
 public class OAuth2LoginConfig {
 
-	@EnableWebSecurity
-	public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeHttpRequests(authorize -> authorize
-					.anyRequest().authenticated()
-				)
-				.oauth2Login(withDefaults());
-		}
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+		http
+			.authorizeHttpRequests(authorize -> authorize
+				.anyRequest().authenticated()
+			)
+			.oauth2Login(withDefaults());
+		return http.build();
 	}
 
 	@Bean
@@ -404,17 +403,15 @@ public class OAuth2LoginConfig {
 @Configuration
 class OAuth2LoginConfig {
 
-    @EnableWebSecurity
-    class OAuth2LoginSecurityConfig: WebSecurityConfigurerAdapter() {
-
-        override fun configure(http: HttpSecurity) {
-            http {
-                authorizeRequests {
-                    authorize(anyRequest, authenticated)
-                }
-                oauth2Login { }
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
+        http {
+            authorizeRequests {
+                authorize(anyRequest, authenticated)
             }
+            oauth2Login { }
         }
+        return http.build()
     }
 
     @Bean
@@ -453,20 +450,17 @@ If you are not able to use Spring Boot 2.x and would like to configure one of th
 .Java
 [source,java,role="primary"]
 ----
-@Configuration
+@EnableWebSecurity
 public class OAuth2LoginConfig {
 
-	@EnableWebSecurity
-	public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeHttpRequests(authorize -> authorize
-					.anyRequest().authenticated()
-				)
-				.oauth2Login(withDefaults());
-		}
+	@Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+		http
+			.authorizeHttpRequests(authorize -> authorize
+				.anyRequest().authenticated()
+			)
+			.oauth2Login(withDefaults());
+		return http.build();
 	}
 
 	@Bean
@@ -498,18 +492,17 @@ public class OAuth2LoginConfig {
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-@Configuration
+@EnableWebSecurity
 open class OAuth2LoginConfig {
-    @EnableWebSecurity
-    open class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
-        override fun configure(http: HttpSecurity) {
-            http {
-                authorizeRequests {
-                    authorize(anyRequest, authenticated)
-                }
-                oauth2Login { }
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
+        http {
+            authorizeRequests {
+                authorize(anyRequest, authenticated)
             }
+            oauth2Login { }
         }
+        return http.build()
     }
 
     @Bean

+ 48 - 24
docs/modules/ROOT/pages/servlet/oauth2/resource-server/jwt.adoc

@@ -137,26 +137,29 @@ This property can also be supplied directly on the <<oauth2resourceserver-jwt-jw
 
 There are two ``@Bean``s that Spring Boot generates on Resource Server's behalf.
 
-The first is a `WebSecurityConfigurerAdapter` that configures the app as a resource server. When including `spring-security-oauth2-jose`, this `WebSecurityConfigurerAdapter` looks like:
+The first is a `SecurityFilterChain` that configures the app as a resource server. When including `spring-security-oauth2-jose`, this `SecurityFilterChain` looks like:
 
 .Default JWT Configuration
 ====
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     http
         .authorizeHttpRequests(authorize -> authorize
             .anyRequest().authenticated()
         )
         .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
+    return http.build();
 }
 ----
 
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         authorizeRequests {
             authorize(anyRequest, authenticated)
@@ -165,11 +168,12 @@ fun configure(http: HttpSecurity) {
             jwt { }
         }
     }
+    return http.build()
 }
 ----
 ====
 
-If the application doesn't expose a `WebSecurityConfigurerAdapter` bean, then Spring Boot will expose the above default one.
+If the application doesn't expose a `SecurityFilterChain` bean, then Spring Boot will expose the above default one.
 
 Replacing this is as simple as exposing the bean within the application:
 
@@ -179,8 +183,9 @@ Replacing this is as simple as exposing the bean within the application:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class MyCustomSecurityConfiguration {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .mvcMatchers("/messages/**").hasAuthority("SCOPE_message:read")
@@ -191,6 +196,7 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
                     .jwtAuthenticationConverter(myConverter())
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -199,8 +205,9 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class MyCustomSecurityConfiguration {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize("/messages/**", hasAuthority("SCOPE_message:read"))
@@ -212,6 +219,7 @@ class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -296,8 +304,9 @@ An authorization server's JWK Set Uri can be configured <<oauth2resourceserver-j
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class DirectlyConfiguredJwkSetUri {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .anyRequest().authenticated()
@@ -307,6 +316,7 @@ public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
                     .jwkSetUri("https://idp.example.com/.well-known/jwks.json")
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -315,8 +325,9 @@ public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class DirectlyConfiguredJwkSetUri {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -327,6 +338,7 @@ class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -356,8 +368,9 @@ More powerful than `jwkSetUri()` is `decoder()`, which will completely replace a
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class DirectlyConfiguredJwtDecoder extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class DirectlyConfiguredJwtDecoder {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .anyRequest().authenticated()
@@ -367,6 +380,7 @@ public class DirectlyConfiguredJwtDecoder extends WebSecurityConfigurerAdapter {
                     .decoder(myCustomDecoder())
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -375,8 +389,9 @@ public class DirectlyConfiguredJwtDecoder extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class DirectlyConfiguredJwtDecoder : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class DirectlyConfiguredJwtDecoder {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -387,6 +402,7 @@ class DirectlyConfiguredJwtDecoder : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -716,8 +732,9 @@ This means that to protect an endpoint or method with a scope derived from a JWT
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class DirectlyConfiguredJwkSetUri {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .mvcMatchers("/contacts/**").hasAuthority("SCOPE_contacts")
@@ -725,6 +742,7 @@ public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
                 .anyRequest().authenticated()
             )
             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
+        return http.build();
     }
 }
 ----
@@ -733,8 +751,9 @@ public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class DirectlyConfiguredJwkSetUri {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize("/contacts/**", hasAuthority("SCOPE_contacts"))
@@ -745,6 +764,7 @@ class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
                 jwt { }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -923,8 +943,9 @@ static class CustomAuthenticationConverter implements Converter<Jwt, AbstractAut
 // ...
 
 @EnableWebSecurity
-public class CustomAuthenticationConverterConfig extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class CustomAuthenticationConverterConfig {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .anyRequest().authenticated()
@@ -934,6 +955,7 @@ public class CustomAuthenticationConverterConfig extends WebSecurityConfigurerAd
                     .jwtAuthenticationConverter(new CustomAuthenticationConverter())
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -950,8 +972,9 @@ internal class CustomAuthenticationConverter : Converter<Jwt, AbstractAuthentica
 // ...
 
 @EnableWebSecurity
-class CustomAuthenticationConverterConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class CustomAuthenticationConverterConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -962,6 +985,7 @@ class CustomAuthenticationConverterConfig : WebSecurityConfigurerAdapter() {
                }
            }
         }
+        return http.build()
     }
 }
 ----

+ 41 - 21
docs/modules/ROOT/pages/servlet/oauth2/resource-server/opaque-token.adoc

@@ -178,27 +178,30 @@ fun forFoosEyesOnly(): String {
 
 There are two ``@Bean``s that Spring Boot generates on Resource Server's behalf.
 
-The first is a `WebSecurityConfigurerAdapter` that configures the app as a resource server.
-When use Opaque Token, this `WebSecurityConfigurerAdapter` looks like:
+The first is a `SecurityFilterChain` that configures the app as a resource server.
+When use Opaque Token, this `SecurityFilterChain` looks like:
 
 .Default Opaque Token Configuration
 ====
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     http
         .authorizeHttpRequests(authorize -> authorize
             .anyRequest().authenticated()
         )
         .oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
+    return http.build();
 }
 ----
 
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-override fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         authorizeRequests {
             authorize(anyRequest, authenticated)
@@ -207,11 +210,12 @@ override fun configure(http: HttpSecurity) {
             opaqueToken { }
         }
     }
+    return http.build()
 }
 ----
 ====
 
-If the application doesn't expose a `WebSecurityConfigurerAdapter` bean, then Spring Boot will expose the above default one.
+If the application doesn't expose a `SecurityFilterChain` bean, then Spring Boot will expose the above default one.
 
 Replacing this is as simple as exposing the bean within the application:
 
@@ -221,8 +225,9 @@ Replacing this is as simple as exposing the bean within the application:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class MyCustomSecurityConfiguration {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .mvcMatchers("/messages/**").hasAuthority("SCOPE_message:read")
@@ -233,6 +238,7 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
                     .introspector(myIntrospector())
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -241,8 +247,9 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class MyCustomSecurityConfiguration {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize("/messages/**", hasAuthority("SCOPE_message:read"))
@@ -254,6 +261,7 @@ class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -335,8 +343,9 @@ An authorization server's Introspection Uri can be configured <<oauth2resourcese
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class DirectlyConfiguredIntrospectionUri extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class DirectlyConfiguredIntrospectionUri {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .anyRequest().authenticated()
@@ -347,6 +356,7 @@ public class DirectlyConfiguredIntrospectionUri extends WebSecurityConfigurerAda
                     .introspectionClientCredentials("client", "secret")
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -355,8 +365,9 @@ public class DirectlyConfiguredIntrospectionUri extends WebSecurityConfigurerAda
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class DirectlyConfiguredIntrospectionUri : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class DirectlyConfiguredIntrospectionUri {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -368,6 +379,7 @@ class DirectlyConfiguredIntrospectionUri : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -397,8 +409,9 @@ More powerful than `introspectionUri()` is `introspector()`, which will complete
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class DirectlyConfiguredIntrospector extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class DirectlyConfiguredIntrospector {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .anyRequest().authenticated()
@@ -408,6 +421,7 @@ public class DirectlyConfiguredIntrospector extends WebSecurityConfigurerAdapter
                     .introspector(myCustomIntrospector())
                 )
             );
+        return http.build();
     }
 }
 ----
@@ -416,8 +430,9 @@ public class DirectlyConfiguredIntrospector extends WebSecurityConfigurerAdapter
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class DirectlyConfiguredIntrospector : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class DirectlyConfiguredIntrospector {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize(anyRequest, authenticated)
@@ -428,6 +443,7 @@ class DirectlyConfiguredIntrospector : WebSecurityConfigurerAdapter() {
                 }
             }
         }
+        return http.build()
     }
 }
 ----
@@ -476,8 +492,9 @@ This means that to protect an endpoint or method with a scope derived from an Op
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class MappedAuthorities extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class MappedAuthorities {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorizeRequests -> authorizeRequests
                 .mvcMatchers("/contacts/**").hasAuthority("SCOPE_contacts")
@@ -485,6 +502,7 @@ public class MappedAuthorities extends WebSecurityConfigurerAdapter {
                 .anyRequest().authenticated()
             )
             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
+        return http.build();
     }
 }
 ----
@@ -493,8 +511,9 @@ public class MappedAuthorities extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class MappedAuthorities : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class MappedAuthorities {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
             authorizeRequests {
                 authorize("/contacts/**", hasAuthority("SCOPE_contacts"))
@@ -505,6 +524,7 @@ class MappedAuthorities : WebSecurityConfigurerAdapter() {
                opaqueToken { }
            }
         }
+        return http.build()
     }
 }
 ----

+ 24 - 15
docs/modules/ROOT/pages/servlet/saml2/login/authentication.adoc

@@ -23,10 +23,10 @@ For that reason, you can configure `OpenSaml4AuthenticationProvider` 's default
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
         authenticationProvider.setAssertionValidator(OpenSaml4AuthenticationProvider
                 .createDefaultAssertionValidator(assertionToken -> {
@@ -44,6 +44,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
             .saml2Login(saml2 -> saml2
                 .authenticationManager(new ProviderManager(authenticationProvider))
             );
+        return http.build();
     }
 }
 ----
@@ -52,8 +53,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class SecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class SecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         val authenticationProvider = OpenSaml4AuthenticationProvider()
         authenticationProvider.setAssertionValidator(
             OpenSaml4AuthenticationProvider
@@ -72,6 +74,7 @@ open class SecurityConfig : WebSecurityConfigurerAdapter() {
                 authenticationManager = ProviderManager(authenticationProvider)
             }
         }
+        return http.build()
     }
 }
 ----
@@ -88,12 +91,12 @@ In that case, the response authentication converter can come in handy, as can be
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
     @Autowired
     UserDetailsService userDetailsService;
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
         authenticationProvider.setResponseAuthenticationConverter(responseToken -> {
             Saml2Authentication authentication = OpenSaml4AuthenticationProvider
@@ -112,6 +115,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
             .saml2Login(saml2 -> saml2
                 .authenticationManager(new ProviderManager(authenticationProvider))
             );
+        return http.build();
     }
 }
 ----
@@ -120,11 +124,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class SecurityConfig : WebSecurityConfigurerAdapter() {
+open class SecurityConfig {
     @Autowired
     var userDetailsService: UserDetailsService? = null
 
-    override fun configure(http: HttpSecurity) {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         val authenticationProvider = OpenSaml4AuthenticationProvider()
         authenticationProvider.setResponseAuthenticationConverter { responseToken: OpenSaml4AuthenticationProvider.ResponseToken ->
             val authentication = OpenSaml4AuthenticationProvider
@@ -143,6 +148,7 @@ open class SecurityConfig : WebSecurityConfigurerAdapter() {
                 authenticationManager = ProviderManager(authenticationProvider)
             }
         }
+        return http.build()
     }
 }
 ----
@@ -304,10 +310,10 @@ This authentication manager should expect a `Saml2AuthenticationToken` object co
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
+    @Bean
+	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         AuthenticationManager authenticationManager = new MySaml2AuthenticationManager(...);
         http
             .authorizeHttpRequests(authorize -> authorize
@@ -317,6 +323,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
                 .authenticationManager(authenticationManager)
             )
         ;
+        return http.build();
     }
 }
 ----
@@ -325,8 +332,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-open class SecurityConfig : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+open class SecurityConfig {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         val customAuthenticationManager: AuthenticationManager = MySaml2AuthenticationManager(...)
         http {
             authorizeRequests {
@@ -336,6 +344,7 @@ open class SecurityConfig : WebSecurityConfigurerAdapter() {
                 authenticationManager = customAuthenticationManager
             }
         }
+        return http.build()
     }
 }
 ----

+ 26 - 14
docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc

@@ -279,38 +279,42 @@ The `requireInitialize` method may only be called once per application instance.
 
 There are two ``@Bean``s that Spring Boot generates for a relying party.
 
-The first is a `WebSecurityConfigurerAdapter` that configures the app as a relying party.
-When including `spring-security-saml2-service-provider`, the `WebSecurityConfigurerAdapter` looks like:
+The first is a `SecurityFilterChain` that configures the app as a relying party.
+When including `spring-security-saml2-service-provider`, the `SecurityFilterChain` looks like:
 
 .Default JWT Configuration
 ====
 .Java
 [source,java,role="primary"]
 ----
-protected void configure(HttpSecurity http) {
+@Bean
+public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     http
         .authorizeHttpRequests(authorize -> authorize
             .anyRequest().authenticated()
         )
         .saml2Login(withDefaults());
+    return http.build();
 }
 ----
 
 .Kotlin
 [source,kotlin,role="secondary"]
 ----
-fun configure(http: HttpSecurity) {
+@Bean
+open fun filterChain(http: HttpSecurity): SecurityFilterChain {
     http {
         authorizeRequests {
             authorize(anyRequest, authenticated)
         }
         saml2Login { }
     }
+    return http.build()
 }
 ----
 ====
 
-If the application doesn't expose a `WebSecurityConfigurerAdapter` bean, then Spring Boot will expose the above default one.
+If the application doesn't expose a `SecurityFilterChain` bean, then Spring Boot will expose the above default one.
 
 You can replace this by exposing the bean within the application:
 
@@ -320,14 +324,16 @@ You can replace this by exposing the bean within the application:
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class MyCustomSecurityConfiguration {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .mvcMatchers("/messages/**").hasAuthority("ROLE_USER")
                 .anyRequest().authenticated()
             )
             .saml2Login(withDefaults());
+        return http.build();
     }
 }
 ----
@@ -336,8 +342,9 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class MyCustomSecurityConfiguration {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize("/messages/**", hasAuthority("ROLE_USER"))
@@ -346,6 +353,7 @@ class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
             saml2Login {
             }
         }
+        return http.build()
     }
 }
 ----
@@ -460,7 +468,7 @@ Note that `X509Support` is an OpenSAML class, used here in the snippet for brevi
 
 [[servlet-saml2login-relyingpartyregistrationrepository-dsl]]
 
-Alternatively, you can directly wire up the repository using the DSL, which will also override the auto-configured `WebSecurityConfigurerAdapter`:
+Alternatively, you can directly wire up the repository using the DSL, which will also override the auto-configured `SecurityFilterChain`:
 
 .Custom Relying Party Registration DSL
 ====
@@ -468,8 +476,9 @@ Alternatively, you can directly wire up the repository using the DSL, which will
 [source,java,role="primary"]
 ----
 @EnableWebSecurity
-public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
-    protected void configure(HttpSecurity http) {
+public class MyCustomSecurityConfiguration {
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
             .authorizeHttpRequests(authorize -> authorize
                 .mvcMatchers("/messages/**").hasAuthority("ROLE_USER")
@@ -478,6 +487,7 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
             .saml2Login(saml2 -> saml2
                 .relyingPartyRegistrationRepository(relyingPartyRegistrations())
             );
+        return http.build();
     }
 }
 ----
@@ -486,8 +496,9 @@ public class MyCustomSecurityConfiguration extends WebSecurityConfigurerAdapter
 [source,kotlin,role="secondary"]
 ----
 @EnableWebSecurity
-class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
-    override fun configure(http: HttpSecurity) {
+class MyCustomSecurityConfiguration {
+    @Bean
+    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
         http {
             authorizeRequests {
                 authorize("/messages/**", hasAuthority("ROLE_USER"))
@@ -497,6 +508,7 @@ class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
                 relyingPartyRegistrationRepository = relyingPartyRegistrations()
             }
         }
+        return http.build()
     }
 }
 ----