Przeglądaj źródła

Add 7.0 -> 8.0 Migration Guide

Closes gh-17182
Josh Cummings 2 miesięcy temu
rodzic
commit
37a814bc29

+ 5 - 8
docs/modules/ROOT/nav.adoc

@@ -2,14 +2,11 @@
 * xref:prerequisites.adoc[Prerequisites]
 * xref:community.adoc[Community]
 * xref:whats-new.adoc[What's New]
-* xref:migration-7/index.adoc[Preparing for 7.0]
-** xref:migration-7/authentication.adoc[Authentication]
-** xref:migration-7/authorization.adoc[Authorization]
-** xref:migration-7/configuration.adoc[Configuration]
-** xref:migration-7/ldap.adoc[LDAP]
-** xref:migration-7/oauth2.adoc[OAuth 2.0]
-** xref:migration-7/web.adoc[Web]
-* xref:migration/index.adoc[Migrating to 6]
+* xref:migration-8/index.adoc[Preparing for 8.0]
+* xref:migration/index.adoc[Migrating to 7]
+** xref:migration/servlet/index.adoc[Servlet]
+*** xref:migration/servlet/oauth2.adoc[OAuth 2.0]
+** xref:migration/reactive.adoc[Reactive]
 * xref:getting-spring-security.adoc[Getting Spring Security]
 * xref:attachment$api/java/index.html[Javadoc]
 * xref:features/index.adoc[Features]

+ 0 - 68
docs/modules/ROOT/pages/migration-7/authentication.adoc

@@ -1,68 +0,0 @@
-= Authentication Changes
-
-== Opaque Token Credentials Will Be Encoded For You
-
-In order to comply more closely with the Introspection RFC, Spring Security's opaque token support will encode the client id and secret before creating the authorization header.
-This change means you will no longer have to encode the client id and secret yourself.
-
-If your client id or secret contain URL-unsafe characters, then you can prepare yourself for this change by doing the following:
-
-=== Replace Usage of `introspectionClientCredentials`
-
-Since Spring Security can now do the encoding for you, replace xref:servlet/oauth2/resource-server/opaque-token.adoc#oauth2resourceserver-opaque-introspectionuri-dsl[using `introspectionClientCredentials`] with publishing the following `@Bean`:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-OpaqueTokenIntrospector introspector() {
-	return SpringOpaqueTokenIntrospector.withIntrospectionUri(introspectionUri)
-            .clientId(unencodedClientId).clientSecret(unencodedClientSecret).build();
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun introspector(): OpaqueTokenIntrospector {
-    return SpringOpaqueTokenIntrospector.withIntrospectionUri(introspectionUri)
-            .clientId(unencodedClientId).clientSecret(unencodedClientSecret).build()
-}
-----
-======
-
-The above will be the default in 7.0.
-
-If this setting gives you trouble or you cannot apply it for now, you can use the `RestOperations` constructor instead:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-OpaqueTokenIntrospector introspector() {
-	RestTemplate rest = new RestTemplate();
-	rest.addInterceptor(new BasicAuthenticationInterceptor(encodedClientId, encodedClientSecret));
-	return new SpringOpaqueTokenIntrospector(introspectionUri, rest);
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun introspector(): OpaqueTokenIntrospector {
-	val rest = RestTemplate()
-	rest.addInterceptor(BasicAuthenticationInterceptor(encodedClientId, encodedClientSecret))
-	return SpringOpaqueTokenIntrospector(introspectionUri, rest)
-}
-----
-======

+ 0 - 24
docs/modules/ROOT/pages/migration-7/authorization.adoc

@@ -1,24 +0,0 @@
-= Authorization Changes
-
-The following sections relate to how to adapt to changes in the authorization support.
-
-== Method Security
-
-[[compile-with-parameters]]
-=== Compile With `-parameters`
-
-Spring Framework 6.1 https://github.com/spring-projects/spring-framework/issues/29559[removes LocalVariableTableParameterNameDiscoverer].
-This affects how `@PreAuthorize` and other xref:servlet/authorization/method-security.adoc[method security] annotations will process parameter names.
-If you are using method security annotations with parameter names, for example:
-
-[source,java]
-.Method security annotation using `id` parameter name
-----
-@PreAuthorize("@authz.checkPermission(#id, authentication)")
-public void doSomething(Long id) {
-    // ...
-}
-----
-
-You must compile with `-parameters` to ensure that the parameter names are available at runtime.
-For more information about this, please visit the https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#core-container[Upgrading to Spring Framework 6.1 page].

+ 0 - 125
docs/modules/ROOT/pages/migration-7/configuration.adoc

@@ -1,125 +0,0 @@
-= Configuration Migrations
-
-The following steps relate to changes around how to configure `HttpSecurity`, `WebSecurity` and related components.
-
-== Use the Lambda DSL
-
-The Lambda DSL is present in Spring Security since version 5.2, and it allows HTTP security to be configured using lambdas.
-
-You may have seen this style of configuration in the Spring Security documentation or samples.
-Let us take a look at how a lambda configuration of HTTP security compares to the previous configuration style.
-
-[source,java]
-.Configuration using lambdas
-----
-@Configuration
-@EnableWebSecurity
-public class SecurityConfig {
-
-    @Bean
-    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
-        http
-            .authorizeHttpRequests(authorize -> authorize
-                .requestMatchers("/blog/**").permitAll()
-                .anyRequest().authenticated()
-            )
-            .formLogin(formLogin -> formLogin
-                .loginPage("/login")
-                .permitAll()
-            )
-            .rememberMe(Customizer.withDefaults());
-
-        return http.build();
-    }
-}
-----
-
-[source,java]
-.Equivalent configuration without using lambdas
-----
-@Configuration
-@EnableWebSecurity
-public class SecurityConfig {
-
-    @Bean
-    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
-        http
-            .authorizeHttpRequests()
-                .requestMatchers("/blog/**").permitAll()
-                .anyRequest().authenticated()
-                .and()
-            .formLogin()
-                .loginPage("/login")
-                .permitAll()
-                .and()
-            .rememberMe();
-
-        return http.build();
-    }
-}
-----
-
-The Lambda DSL is the preferred way to configure Spring Security, the prior configuration style will not be valid in Spring Security 7 where the usage of the Lambda DSL will be required.
-This has been done mainly for a couple of reasons:
-
-- The previous way it was not clear what object was getting configured without knowing what the return type was.
-The deeper the nesting the more confusing it became.
-Even experienced users would think that their configuration was doing one thing when in fact, it was doing something else.
-
-- Consistency.
-Many code bases switched between the two styles which caused inconsistencies that made understanding the configuration difficult and often led to misconfigurations.
-
-=== Lambda DSL Configuration Tips
-
-When comparing the two samples above, you will notice some key differences:
-
-- In the Lambda DSL there is no need to chain configuration options using the `.and()` method.
-The `HttpSecurity` instance is automatically returned for further configuration after the call to the lambda method.
-
-- `Customizer.withDefaults()` enables a security feature using the defaults provided by Spring Security.
-This is a shortcut for the lambda expression `it -> {}`.
-
-=== WebFlux Security
-
-You may also configure WebFlux security using lambdas in a similar manner.
-Below is an example configuration using lambdas.
-
-[source,java]
-.WebFlux configuration using lambdas
-----
-@Configuration
-@EnableWebFluxSecurity
-public class SecurityConfig {
-
-    @Bean
-    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
-        http
-            .authorizeExchange(exchanges -> exchanges
-                .pathMatchers("/blog/**").permitAll()
-                .anyExchange().authenticated()
-            )
-            .httpBasic(Customizer.withDefaults())
-            .formLogin(formLogin -> formLogin
-                .loginPage("/login")
-            );
-
-        return http.build();
-    }
-
-}
-----
-
-=== Goals of the Lambda DSL
-
-The Lambda DSL was created to accomplish to following goals:
-
-- Automatic indentation makes the configuration more readable.
-- There is no need to chain configuration options using `.and()`
-- The Spring Security DSL has a similar configuration style to other Spring DSLs such as Spring Integration and Spring Cloud Gateway.
-
-== Use `.with()` instead of `.apply()` for Custom DSLs
-
-In versions prior to 6.2, if you had a xref:servlet/configuration/java.adoc#jc-custom-dsls[custom DSL], you would apply it to the `HttpSecurity` using the `HttpSecurity#apply(...)` method.
-However, starting from version 6.2, this method is deprecated and will be removed in 7.0 because it will no longer be possible to chain configurations using `.and()` once `.and()` is removed (see https://github.com/spring-projects/spring-security/issues/13067).
-Instead, it is recommended to use the new `.with(...)` method.
-For more information about how to use `.with(...)` please refer to the xref:servlet/configuration/java.adoc#jc-custom-dsls[Custom DSLs section].

+ 0 - 11
docs/modules/ROOT/pages/migration-7/ldap.adoc

@@ -1,11 +0,0 @@
-= LDAP Migrations
-
-The following steps relate to changes around how to configure the LDAP components and how to use an embedded LDAP server.
-
-== Use `UnboundId` instead of `ApacheDS`
-
-ApacheDS has not had a GA release for a considerable period, and its classes in Spring Security were https://github.com/spring-projects/spring-security/pull/6376[deprecated in version 5.2].
-Consequently, support for ApacheDS will be discontinued in version 7.0.
-
-If you are currently using ApacheDS as an embedded LDAP server, we recommend migrating to https://ldap.com/unboundid-ldap-sdk-for-java/[UnboundId].
-You can find instructions in xref:servlet/authentication/passwords/ldap.adoc#servlet-authentication-ldap-embedded[this section] that describe how to set up an embedded UnboundId LDAP server.

+ 0 - 172
docs/modules/ROOT/pages/migration-7/oauth2.adoc

@@ -1,172 +0,0 @@
-= OAuth 2.0 Changes
-
-== Validate `typ` Header with `JwtTypeValidator`
-
-`NimbusJwtDecoder` in Spring Security 7 will move `typ` header validation to `JwtTypeValidator` instead of relying on Nimbus.
-This brings it in line with `NimbusJwtDecoder` validating claims instead of relying on Nimbus to validate them.
-
-If you are changing Nimbus's default type validation in a `jwtProcessorCustomizer` method, then you should move that to `JwtTypeValidator` or an implementation of `OAuth2TokenValidator` of your own.
-
-To check if you are prepared for this change, add the default `JwtTypeValidator` to your list of validators, as this will be included by default in 7:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-JwtDecoder jwtDecoder() {
-	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(false) <1>
-        // ... your remaining configuration
-        .build();
-	jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
-		new JwtIssuerValidator(location), JwtTypeValidator.jwt())); <2>
-	return jwtDecoder;
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun jwtDecoder(): JwtDecoder {
-    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(false) <1>
-        // ... your remaining configuration
-        .build()
-    jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
-        JwtIssuerValidator(location), JwtTypeValidator.jwt())) <2>
-    return jwtDecoder
-}
-----
-======
-<1> - Switch off Nimbus verifying the `typ` (this will be off by default in 7)
-<2> - Add the default `typ` validator (this will be included by default in 7)
-
-Note the default value verifies that the `typ` value either be `JWT` or not present, which is the same as the Nimbus default.
-It is also aligned with https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.9[RFC 7515] which states that `typ` is optional.
-
-
-=== I'm Using A `DefaultJOSEObjectTypeVerifier`
-
-If you have something like the following in your configuration:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-JwtDecoder jwtDecoder() {
-	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .jwtProcessorCustomizer((c) -> c
-            .setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>("JOSE"))
-        )
-        .build();
-	return jwtDecoder;
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun jwtDecoder(): JwtDecoder {
-    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .jwtProcessorCustomizer {
-            it.setJWSTypeVerifier(DefaultJOSEObjectTypeVerifier("JOSE"))
-        }
-        .build()
-    return jwtDecoder
-}
-----
-======
-
-Then change this to:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-JwtDecoder jwtDecoder() {
-	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(false)
-        .build();
-	jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
-		new JwtIssuerValidator(location), new JwtTypeValidator("JOSE")));
-	return jwtDecoder;
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun jwtDecoder(): JwtDecoder {
-    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(false)
-        .build()
-	jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
-		JwtIssuerValidator(location), JwtTypeValidator("JOSE")))
-    return jwtDecoder
-}
-----
-======
-
-To indicate that the `typ` header is optional, use `#setAllowEmpty(true)` (this is the equivalent of including `null` in the list of allowed types in `DefaultJOSEObjectTypeVerifier`).
-
-=== I want to opt-out
-
-If you want to keep doing things the way that you are, then the steps are similar, just in reverse:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-JwtDecoder jwtDecoder() {
-	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(true) <1>
-        .jwtProcessorCustomizer((c) -> c
-            .setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>("JOSE"))
-        )
-        .build();
-	jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
-		new JwtTimestampValidator(), new JwtIssuerValidator(location))); <2>
-	return jwtDecoder;
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun jwtDecoder(): JwtDecoder {
-    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
-        .validateTypes(true) <1>
-        .jwtProcessorCustomizer {
-            it.setJWSTypeVerifier(DefaultJOSEObjectTypeVerifier("JOSE"))
-        }
-        .build()
-	jwtDecoder.setJwtValidator(DelegatingOAuth2TokenValidator(
-        JwtTimestampValidator(), JwtIssuerValidator(location))) <2>
-    return jwtDecoder
-}
-----
-======
-<1> - leave Nimbus type verification on
-<2> - specify the list of validators you need, excluding `JwtTypeValidator`
-
-For additional guidance, please see the xref:servlet/oauth2/resource-server/jwt.adoc#oauth2resourceserver-jwt-validation[JwtDecoder Validators] section in the reference.

+ 0 - 165
docs/modules/ROOT/pages/migration-7/saml2.adoc

@@ -1,165 +0,0 @@
-= Saml 2.0 Migrations
-
-== Continue Filter Chain When No Relying Party Found
-
-In Spring Security 6, `Saml2WebSsoAuthenticationFilter` throws an exception when the request URI matches, but no relying party registration is found.
-
-There are a number of cases when an application would not consider this an error situation.
-For example, this filter doesn't know how the `AuthorizationFilter` will respond to a missing relying party.
-In some cases it may be allowable.
-
-In other cases, you may want your `AuthenticationEntryPoint` to be invoked, which would happen if this filter were to allow the request to continue to the `AuthorizationFilter`.
-
-To improve this filter's flexibility, in Spring Security 7 it will continue the filter chain when there is no relying party registration found instead of throwing an exception.
-
-For many applications, the only notable change will be that your `authenticationEntryPoint` will be invoked if the relying party registration cannot be found.
-When you have only one asserting party, this means by default a new authentication request will be built and sent back to the asserting party, which may cause a "Too Many Redirects" loop.
-
-To see if you are affected in this way, you can prepare for this change in 6 by setting the following property in `Saml2WebSsoAuthenticationFilter`:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    .saml2Login((saml2) -> saml2
-        .withObjectPostProcessor(new ObjectPostProcessor<Saml2WebSsoAuhenticaionFilter>() {
-			@Override
-            public Saml2WebSsoAuthenticationFilter postProcess(Saml2WebSsoAuthenticationFilter filter) {
-				filter.setContinueChainWhenNoRelyingPartyRegistrationFound(true);
-				return filter;
-            }
-        })
-    )
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-http {
-    saml2Login { }
-    withObjectPostProcessor(
-        object : ObjectPostProcessor<Saml2WebSsoAuhenticaionFilter?>() {
-            override fun postProcess(filter: Saml2WebSsoAuthenticationFilter): Saml2WebSsoAuthenticationFilter {
-            filter.setContinueChainWhenNoRelyingPartyRegistrationFound(true)
-            return filter
-        }
-    })
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<b:bean id="saml2PostProcessor" class="org.example.MySaml2WebSsoAuthenticationFilterBeanPostProcessor"/>
-----
-======
-
-== Validate Response After Validating Assertions
-
-In Spring Security 6, the order of authenticating a `<saml2:Response>` is as follows:
-
-1. Verify the Response Signature, if any
-2. Decrypt the Response
-3. Validate Response attributes, like Destination and Issuer
-4. For each assertion, verify the signature, decrypt, and then validate its fields
-5. Check to ensure that the response has at least one assertion with a name field
-
-This ordering sometimes poses challenges since some response validation is being done in Step 3 and some in Step 5.
-Specifically, this poses a chellenge when an application doesn't have a name field and doesn't need it to be validated.
-
-In Spring Security 7, this is simplified by moving response validation to after assertion validation and combining the two separate validation steps 3 and 5.
-When this is complete, response validation will no longer check for the existence of the `NameID` attribute and rely on ``ResponseAuthenticationConverter``s to do this.
-
-This will add support ``ResponseAuthenticationConverter``s that don't use the `NameID` element in their `Authentication` instance and so don't need it validated.
-
-To opt-in to this behavior in advance, use `OpenSaml5AuthenticationProvider#setValidateResponseAfterAssertions` to `true` like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
-provider.setValidateResponseAfterAssertions(true);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val provider = OpenSaml5AuthenticationProvider()
-provider.setValidateResponseAfterAssertions(true)
-----
-======
-
-This will change the authentication steps as follows:
-
-1. Verify the Response Signature, if any
-2. Decrypt the Response
-3. For each assertion, verify the signature, decrypt, and then validate its fields
-4. Validate Response attributes, like Destination and Issuer
-
-Note that if you have a custom response authentication converter, then you are now responsible to check if the `NameID` element exists in the event that you need it.
-
-Alternatively to updating your response authentication converter, you can specify a custom `ResponseValidator` that adds back in the check for the `NameID` element as follows:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
-provider.setValidateResponseAfterAssertions(true);
-ResponseValidator responseValidator = ResponseValidator.withDefaults((responseToken) -> {
-	Response response = responseToken.getResponse();
-	Assertion assertion = CollectionUtils.firstElement(response.getAssertions());
-	Saml2Error error = new Saml2Error(Saml2ErrorCodes.SUBJECT_NOT_FOUND,
-            "Assertion [" + firstAssertion.getID() + "] is missing a subject");
-	Saml2ResponseValidationResult failed = Saml2ResponseValidationResult.failure(error);
-	if (assertion.getSubject() == null) {
-		return failed;
-	}
-	if (assertion.getSubject().getNameID() == null) {
-		return failed;
-	}
-	if (assertion.getSubject().getNameID().getValue() == null) {
-		return failed;
-	}
-	return Saml2ResponseValidationResult.success();
-});
-provider.setResponseValidator(responseValidator);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val provider = OpenSaml5AuthenticationProvider()
-provider.setValidateResponseAfterAssertions(true)
-val responseValidator = ResponseValidator.withDefaults { responseToken: ResponseToken ->
-	val response = responseToken.getResponse()
-	val assertion = CollectionUtils.firstElement(response.getAssertions())
-	val error = Saml2Error(Saml2ErrorCodes.SUBJECT_NOT_FOUND,
-        "Assertion [" + firstAssertion.getID() + "] is missing a subject")
-	val failed = Saml2ResponseValidationResult.failure(error)
-	if (assertion.getSubject() == null) {
-        return@withDefaults failed
-	}
-	if (assertion.getSubject().getNameID() == null) {
-		return@withDefaults failed
-	}
-	if (assertion.getSubject().getNameID().getValue() == null) {
-		return@withDefaults failed
-	}
-	return@withDefaults Saml2ResponseValidationResult.success()
-}
-provider.setResponseValidator(responseValidator)
-----
-======

+ 0 - 523
docs/modules/ROOT/pages/migration-7/web.adoc

@@ -1,523 +0,0 @@
-= Web Migrations
-
-== Favor Relative URIs
-
-When redirecting to a login endpoint, Spring Security has favored absolute URIs in the past.
-For example, if you set your login page like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    // ...
-    .formLogin((form) -> form.loginPage("/my-login"))
-    // ...
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-http {
-    formLogin {
-        loginPage = "/my-login"
-    }
-}
-----
-
-Xml::
-+
-[source,kotlin,role="secondary"]
-----
-<http ...>
-    <form-login login-page="/my-login"/>
-</http>
-----
-======
-
-then when redirecting to `/my-login` Spring Security would use a `Location:` like the following:
-
-[source]
-----
-302 Found
-// ...
-Location: https://myapp.example.org/my-login
-----
-
-However, this is no longer necessary given that the RFC is was based on is now obsolete.
-
-In Spring Security 7, this is changed to use a relative URI like so:
-
-[source]
-----
-302 Found
-// ...
-Location: /my-login
-----
-
-Most applications will not notice a difference.
-However, in the event that this change causes problems, you can switch back to the Spring Security 6 behavior by setting the `favorRelativeUrls` value:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/my-login");
-entryPoint.setFavorRelativeUris(false);
-http
-    // ...
-    .exceptionHandling((exceptions) -> exceptions.authenticaitonEntryPoint(entryPoint))
-    // ...
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-LoginUrlAuthenticationEntryPoint entryPoint = LoginUrlAuthenticationEntryPoint("/my-login")
-entryPoint.setFavorRelativeUris(false)
-
-http {
-    exceptionHandling {
-        authenticationEntryPoint = entryPoint
-    }
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<http entry-point-ref="myEntryPoint">
-    <!-- ... -->
-</http>
-
-<b:bean id="myEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
-    <b:property name="favorRelativeUris" value="true"/>
-</b:bean>
-----
-======
-
-== PortResolver
-
-Spring Security uses an API called `PortResolver` to provide a workaround for a bug in Internet Explorer.
-The workaround is no longer necessary and can cause users problems in some scenarios.
-For this reason, Spring Security 7 will remove the `PortResolver` interface.
-
-To prepare for this change, users should expose the `PortResolver.NO_OP` as a Bean named `portResolver`.
-This ensures that the `PortResolver` implementation that is used is a no-op (e.g. does nothing) which simulates the removal of `PortResolver`.
-An example configuration can be found below:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-PortResolver portResolver() {
-	return PortResolver.NO_OP;
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-open fun portResolver(): PortResolver {
-    return PortResolver.NO_OP
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-
-<util:constant id="portResolver"
-    static-field="org.springframework.security.web.PortResolver.NO_OP">
-----
-======
-
-[[use-path-pattern]]
-== Use PathPatternRequestMatcher by Default
-
-In Spring Security 7, `AntPathRequestMatcher` and `MvcRequestMatcher` are no longer supported and the Java DSL requires that all URIs be absolute (less any context root).
-At that time, Spring Security 7 will use `PathPatternRequestMatcher` by default.
-
-To check how prepared you are for this change, you can publish this bean:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-PathPatternRequestMatcherBuilderFactoryBean requestMatcherBuilder() {
-	return new PathPatternRequestMatcherBuilderFactoryBean();
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun requestMatcherBuilder(): PathPatternRequestMatcherBuilderFactoryBean {
-    return PathPatternRequestMatcherBuilderFactoryBean()
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<b:bean class="org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean"/>
-----
-======
-
-This will tell the Spring Security DSL to use `PathPatternRequestMatcher` for all request matchers that it constructs.
-
-In the event that you are directly constructing an object (as opposed to having the DSL construct it) that has a `setRequestMatcher` method. you should also proactively specify a `PathPatternRequestMatcher` there as well.
-
-=== Migrate `exitUserUrl` and `switchUserUrl` Request Matchers in `SwitchUserFilter`
-
-`SwitchUserFilter`, constructs an `AntPathRequestMatcher` in its `setExitUserUrl` and `setSwitchUserUrl` methods.
-This will change to use `PathPatternRequestMatcher` in Spring Security 7.
-
-To prepare for this change, call `setExitUserMatcher` and `setSwithcUserMatcher` to provide this `PathPatternRequestMatcher` in advance.
-That is, change this:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-SwitchUserFilter switchUser = new SwitchUserFilter();
-// ... other configuration
-switchUser.setExitUserUrl("/exit/impersonate");
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val switchUser = SwitchUserFilter()
-// ... other configuration
-switchUser.setExitUserUrl("/exit/impersonate")
-----
-======
-
-to this:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-SwitchUserFilter switchUser = new SwitchUserFilter();
-// ... other configuration
-switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"));
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val switchUser = SwitchUserFilter()
-// ... other configuration
-switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"))
-----
-======
-
-=== Migrate `filterProcessingUrl` Request Matcher in `AbstractAuthenticationProcessingFilter` Implementations
-
-Spring Security 6 converts any processing endpoint configured through `setFilterProcessingUrl` to an `AntPathRequestMatcher`.
-In Spring Security 7, this will change to `PathPatternRequestMatcher`.
-
-If you are directly invoking `setFilterProcessingUrl` on a filter that extends `AbstractAuthenticationProcessingFilter`, like `UsernamePasswordAuthenticationFilter`, `OAuth2LoginAuthenticationFilter`, `Saml2WebSsoAuthenticationFilter`, `OneTimeTokenAuthenticationFilter`, or `WebAuthnAuthenticationFilter`, call `setRequiredAuthenticationRequestMatcher` instead to provide this `PathPatternRequestMatcher` in advance.
-
-That is, change this:
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager);
-usernamePassword.setFilterProcessingUrl("/my/processing/url");
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager)
-usernamePassword.setFilterProcessingUrl("/my/processing/url")
-----
-======
-
-to this:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager);
-RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url");
-usernamePassword.setRequest(requestMatcher);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager)
-val requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url")
-usernamePassword.setRequest(requestMatcher)
-----
-======
-
-[NOTE]
------
-Most applications use the DSL instead of setting the `filterProcessingUrl` directly on a filter instance.
------
-
-=== Migrate CAS Proxy Receptor Request Matcher
-
-Spring Security 6 converts any configured `proxyReceptorUrl` to a request matcher that matches the end of the request, that is `/**/proxy/receptor`.
-In Spring Security 7, this pattern is not allowed and will change to using `PathPatternRequestMatcher`.
-Also in Spring Security 7m the URL should by absolute, excluding any context path, like so: `/proxy/receptor`.
-
-So to prepare for these change, you can use `setProxyReceptorRequestMatcher` instead of `setProxyReceptorUrl`.
-
-That is, change this:
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-casAuthentication.setProxyReceptorUrl("/proxy/receptor");
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-casAuthentication.setProxyReceptorUrl("/proxy/receptor")
-----
-======
-
-to this:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"));
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"))
-----
-======
-
-=== Migrate your WebInvocationPrivilegeEvaluator
-
-If you are using Spring Security's JSP Taglibs or are using `WebInvocationPrivilegeEvaluator` directly, be aware of the following changes:
-
-1. `RequestMatcherWebInvocationPrivilegeEvaluator` is deprecated in favor of `AuthorizationManagerWebInvocationPrivilegeEvaluator`
-2. `HandlerMappingIntrospectorRequestTransformer` is deprecated in favor of `PathPatternRequestTransformer`
-
-If you are not constructing these directly, you can opt-in to both changes in advance by publishing a `PathPatternRequestTransformer` like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-HttpServletRequestTransformer pathPatternRequestTransformer() {
-	return new PathPatternRequestTransformer();
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun pathPatternRequestTransformer(): HttpServletRequestTransformer {
-    return PathPatternRequestTransformer()
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<b:bean class="org.springframework.security.web.access.PathPatternRequestTransformer"/>
-----
-======
-
-Spring Security will take this as a signal to use the new implementations.
-
-[[NOTE]]
-----
-One difference you may notice is that `AuthorizationManagerWebPrivilegeInvocationEvaluator` allows the authentication to be `null` if the authorization rule is `permitAll`.
-
-Test your endpoints that `permitAll` in case JSP requests using this same require should not, in fact, be permitted.
-----
-
-== Include the Servlet Path Prefix in Authorization Rules
-
-For many applications <<use-path-pattern, the above>> will make no difference since most commonly all URIs listed are matched by the default servlet.
-
-However, if you have other servlets with servlet path prefixes, xref:servlet/authorization/authorize-http-requests.adoc[then these paths now need to be supplied separately].
-
-For example, if I have a Spring MVC controller with `@RequestMapping("/orders")` and my MVC application is deployed to `/mvc` (instead of the default servlet), then the URI for this endpoint is `/mvc/orders`.
-Historically, the Java DSL hasn't had a simple way to specify the servlet path prefix and Spring Security attempted to infer it.
-
-Over time, we learned that these inference would surprise developers.
-Instead of taking this responsibility away from developers, now it is simpler to specify the servlet path prefix like so:
-
-[method,java]
-----
-PathPatternRequestParser.Builder servlet = PathPatternRequestParser.withDefaults().basePath("/mvc");
-http
-    .authorizeHttpRequests((authorize) -> authorize
-        .requestMatchers(servlet.pattern("/orders/**").matcher()).authenticated()
-    )
-----
-
-
-For paths that belong to the default servlet, use `PathPatternRequestParser.withDefaults()` instead:
-
-[method,java]
-----
-PathPatternRequestParser.Builder request = PathPatternRequestParser.withDefaults();
-http
-    .authorizeHttpRequests((authorize) -> authorize
-        .requestMatchers(request.pattern("/js/**").matcher()).authenticated()
-    )
-----
-
-Note that this doesn't address every kind of servlet since not all servlets have a path prefix.
-For example, expressions that match the JSP Servlet might use an ant pattern `/**/*.jsp`.
-
-There is not yet a general-purpose replacement for these, and so you are encouraged to use `RegexRequestMatcher`, like so:  `regexMatcher("\\.jsp$")`.
-
-For many applications this will make no difference since most commonly all URIs listed are matched by the default servlet.
-
-[[use-redirect-to-https]]
-== Use RedirectToHttps Instead of Channel Security
-
-Years ago, HTTPS at large was enough of a performance and configuration concern that applications wanted to be able to decide which segments of an application would require HTTPS.
-
-`requires-channel` in XML and `requiresChannel` in Java Config allowed configurating an application with that in mind:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    .requiresChannel((channel) -> channel
-        .requestMatchers("/secure/**").requiresSecureChannel()
-        .requestMatchers("/insecure/**").requiresInsecureChannel()
-    )
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-http {
-    requiresChannel {
-        secure("/secure/**")
-        seccure("/insecure/**", "REQUIRES_INSECURE_CHANNEL")
-    }
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<http>
-    <intercept-url pattern="/secure/**" access="authenticated" requires-channel="REQUIRES_SECURE_CHANNEL"/>
-    <intercept-url pattern="/insecure/**" access="authenticated" requires-channel="REQUIRES_INSECURE_CHANNEL"/>
-</http>
-----
-======
-
-Modern applications should either always require HTTPS.
-However, there are times, like when developing locally, when one would like the application to use HTTP.
-Or, you may have continuing circumstances that require part of your application to be HTTP.
-
-In any case, you can migrate to `redirect-to-https-request-matcher-ref` and `redirectToHttps` by first constructing a `RequestMatcher` that contains all circumstances where redirecting to HTTPS is needed.
-Then you can reference that request matcher like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    .redirectToHttps((https) -> https.requestMatchers("/secure/**"))
-    // ...
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-var secure: RequestMatcher = PathPatternRequestMatcher.withDefaults().pattern("/secure/**")
-http {
-    redirectToHttps {
-        requestMatchers = secure
-    }
-    // ...
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<b:bean id="builder" class="org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher$Builder"/>
-<b:bean id="secure" class="org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher" factory-bean="builder" factory-method="matcher">
-    <b:constructor-arg value="/secure/**"/>
-</b:bean>
-<http redirect-to-https-request-matcher-ref="secure">
-    <intercept-url pattern="/secure/**" access="authenticated"/>
-    <intercept-url pattern="/insecure/**" access="authenticated"/>
-    <!-- ... -->
-</http>
-----
-======
-
-[TIP]
-=====
-If you have several circumstances where HTTP is needed, consider using `OrRequestMatcher` to combine them into a single `RequestMatcher` instance.
-=====

+ 4 - 4
docs/modules/ROOT/pages/migration-7/index.adoc → docs/modules/ROOT/pages/migration-8/index.adoc

@@ -1,9 +1,9 @@
 [[preparing]]
-= Preparing for 7.0
+= Preparing for 8.0
 :page-section-summary-toc: 1
 
-While Spring Security 7.0 does not have a release date yet, it is important to start preparing for it now.
+While Spring Security 8.0 does not have a release date yet, it is important to start preparing for it now.
 
-This preparation guide is designed to summarize the biggest changes in Spring Security 7.0 and provide steps to prepare for them.
+This preparation guide is designed to summarize the biggest changes in Spring Security 8.0 and provide steps to prepare for them.
 
-It is important to keep your application up to date with the latest Spring Security 6 and Spring Boot 3 releases.
+It is important to keep your application up to date with the latest Spring Security 7 and Spring Boot 4 releases.

+ 9 - 23
docs/modules/ROOT/pages/migration/index.adoc

@@ -1,34 +1,20 @@
 [[migration]]
-= Migrating to 6.0
+= Migrating to 7.0
 :spring-security-reference-base-url: https://docs.spring.io/spring-security/reference
 
-The Spring Security team has prepared the 5.8 release to simplify upgrading to Spring Security 6.0.
-Use 5.8 and
-ifdef::spring-security-version[]
-{spring-security-reference-base-url}/5.8/migration/index.html[its preparation steps]
-endif::[]
-ifndef::spring-security-version[]
-its preparation steps
-endif::[]
-to simplify updating to 6.0.
+Spring Security 6.5 is the last release in the 6.x generation of Spring Security.
+It provides strategies for configuring breaking changes to use the 7.0 way before updating.
+We recommend you use 6.5 and {spring-security-reference-base-url}/6.5/migration-7/index.html[its preparation steps] to simplify updating to 7.0.
 
-After updating to 5.8, follow this guide to perform any remaining migration or cleanup steps.
+After updating to 6.5, follow this guide to perform any remaining migration or cleanup steps.
 
 And recall that if you run into trouble, the preparation guide includes opt-out steps to revert to 5.x behaviors.
 
-== Update to Spring Security 6
+== Update to Spring Security 7
 
-The first step is to ensure you are the latest patch release of Spring Boot 3.0.
-Next, you should ensure you are on the latest patch release of Spring Security 6.
-For directions, on how to update to Spring Security 6 visit the xref:getting-spring-security.adoc[] section of the reference guide.
-
-== Update Package Names
-
-Now that you are updated, you need to change your `javax` imports to `jakarta` imports.
-
-== Compile With `--parameters`
-
-If you are using method parameter names in `@PreAuthorize`, `@PostAuthorize`, or any other method security annotations, you may need to xref:migration/servlet/authorization.adoc#compile-with-parameters[compile with `-parameters`].
+The first step is to ensure you are the latest patch release of Spring Boot 4.0.
+Next, you should ensure you are on the latest patch release of Spring Security 7.
+For directions, on how to update to Spring Security 7 visit the xref:getting-spring-security.adoc[] section of the reference guide.
 
 == Perform Application-Specific Steps
 

+ 0 - 97
docs/modules/ROOT/pages/migration/reactive.adoc

@@ -1,100 +1,3 @@
 = Reactive
 
 If you have already performed the xref:migration/index.adoc[initial migration steps] for your Reactive application, you're now ready to perform steps specific to Reactive applications.
-
-== Use `AuthorizationManager` for Method Security
-
-In 6.0, `@EnableReactiveMethodSecurity` defaults `useAuthorizationManager` to `true`.
-So, to complete migration, {security-api-url}org/springframework/security/config/annotation/method/configuration/EnableReactiveMethodSecurity.html[`@EnableReactiveMethodSecurity`] remove the `useAuthorizationManager` attribute:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@EnableReactiveMethodSecurity(useAuthorizationManager = true)
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@EnableReactiveMethodSecurity(useAuthorizationManager = true)
-----
-======
-
-changes to:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@EnableReactiveMethodSecurity
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@EnableReactiveMethodSecurity
-----
-======
-
-== Propagate ``AuthenticationServiceException``s
-
-{security-api-url}org/springframework/security/web/server/authentication/AuthenticationWebFilter.html[`AuthenticationWebFilter`] propagates {security-api-url}org/springframework/security/authentication/AuthenticationServiceException.html[``AuthenticationServiceException``]s to the {security-api-url}org/springframework/security/web/server/ServerAuthenticationEntryPoint.html[`ServerAuthenticationEntryPoint`].
-Because ``AuthenticationServiceException``s represent a server-side error instead of a client-side error, in 6.0, this changes to propagate them to the container.
-
-So, if you opted into this behavior by setting `rethrowAuthenticationServiceException` too `true`, you can now remove it like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-AuthenticationFailureHandler bearerFailureHandler = new ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint);
-bearerFailureHandler.setRethrowAuthenticationServiceException(true);
-AuthenticationFailureHandler basicFailureHandler = new ServerAuthenticationEntryPointFailureHandler(basicEntryPoint);
-basicFailureHandler.setRethrowAuthenticationServiceException(true);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val bearerFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint)
-bearerFailureHandler.setRethrowAuthenticationServiceException(true)
-val basicFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(basicEntryPoint)
-basicFailureHandler.setRethrowAuthenticationServiceException(true)
-----
-======
-
-changes to:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-AuthenticationFailureHandler bearerFailureHandler = new ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint);
-AuthenticationFailureHandler basicFailureHandler = new ServerAuthenticationEntryPointFailureHandler(basicEntryPoint);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val bearerFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint)
-val basicFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(basicEntryPoint)
-----
-======
-
-[NOTE]
-====
-If you configured the `ServerAuthenticationFailureHandler` only for the purpose of updating to 6.0, you can remove it completely.
-====

+ 0 - 187
docs/modules/ROOT/pages/migration/servlet/authentication.adoc

@@ -1,187 +0,0 @@
-= Authentication Migrations
-
-The following steps relate to how to finish migrating authentication support.
-
-== Propagate ``AuthenticationServiceException``s
-
-{security-api-url}org/springframework/security/web/authentication/AuthenticationFilter.html[`AuthenticationFilter`] propagates {security-api-url}org/springframework/security/authentication/AuthenticationServiceException.html[``AuthenticationServiceException``]s to the {security-api-url}org/springframework/security/web/AuthenticationEntryPoint.html[`AuthenticationEntryPoint`].
-Because ``AuthenticationServiceException``s represent a server-side error instead of a client-side error, in 6.0, this changes to propagate them to the container.
-
-So, if you opted into this behavior by setting `rethrowAuthenticationServiceException` to `true`, you can now remove it like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-AuthenticationFilter authenticationFilter = new AuthenticationFilter(...);
-AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(...);
-handler.setRethrowAuthenticationServiceException(true);
-authenticationFilter.setAuthenticationFailureHandler(handler);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val authenticationFilter: AuthenticationFilter = AuthenticationFilter(...)
-val handler: AuthenticationEntryPointFailureHandler = AuthenticationEntryPointFailureHandler(...)
-handler.setRethrowAuthenticationServiceException(true)
-authenticationFilter.setAuthenticationFailureHandler(handler)
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<bean id="authenticationFilter" class="org.springframework.security.web.authentication.AuthenticationFilter">
-    <!-- ... -->
-    <property ref="authenticationFailureHandler"/>
-</bean>
-
-<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler">
-    <property name="rethrowAuthenticationServiceException" value="true"/>
-</bean>
-----
-======
-
-changes to:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-AuthenticationFilter authenticationFilter = new AuthenticationFilter(...);
-AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(...);
-authenticationFilter.setAuthenticationFailureHandler(handler);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val authenticationFilter: AuthenticationFilter = AuthenticationFilter(...)
-val handler: AuthenticationEntryPointFailureHandler = AuthenticationEntryPointFailureHandler(...)
-authenticationFilter.setAuthenticationFailureHandler(handler)
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<bean id="authenticationFilter" class="org.springframework.security.web.authentication.AuthenticationFilter">
-    <!-- ... -->
-    <property ref="authenticationFailureHandler"/>
-</bean>
-
-<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler">
-    <!-- ... -->
-</bean>
-----
-======
-
-[[servlet-opt-in-sha256-rememberme]]
-== Use SHA-256 in Remember Me
-
-In 6.0, the `TokenBasedRememberMeServices` uses SHA-256 to encode and match the token.
-To complete the migration, any default values can be removed.
-
-For example, if you opted in to the 6.0 default for `encodingAlgorithm` and `matchingAlgorithm` like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Configuration
-@EnableWebSecurity
-public class SecurityConfig {
-    @Bean
-    SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception {
-        http
-                // ...
-                .rememberMe((remember) -> remember
-                    .rememberMeServices(rememberMeServices)
-                );
-        return http.build();
-    }
-    @Bean
-    RememberMeServices rememberMeServices(UserDetailsService userDetailsService) {
-        RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256;
-        TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices(myKey, userDetailsService, encodingAlgorithm);
-        rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.SHA256);
-        return rememberMe;
-    }
-}
-----
-
-XML::
-+
-[source,xml,role="secondary"]
-----
-<http>
-  <remember-me services-ref="rememberMeServices"/>
-</http>
-<bean id="rememberMeServices" class=
-"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
-    <property name="userDetailsService" ref="myUserDetailsService"/>
-    <property name="key" value="springRocks"/>
-    <property name="matchingAlgorithm" value="SHA256"/>
-    <property name="encodingAlgorithm" value="SHA256"/>
-</bean>
-----
-======
-
-then the defaults can be removed:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Configuration
-@EnableWebSecurity
-public class SecurityConfig {
-    @Bean
-    SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception {
-        http
-                // ...
-                .rememberMe((remember) -> remember
-                    .rememberMeServices(rememberMeServices)
-                );
-        return http.build();
-    }
-    @Bean
-    RememberMeServices rememberMeServices(UserDetailsService userDetailsService) {
-        return new TokenBasedRememberMeServices(myKey, userDetailsService);
-    }
-}
-----
-
-XML::
-+
-[source,xml,role="secondary"]
-----
-<http>
-  <remember-me services-ref="rememberMeServices"/>
-</http>
-<bean id="rememberMeServices" class=
-"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
-    <property name="userDetailsService" ref="myUserDetailsService"/>
-    <property name="key" value="springRocks"/>
-</bean>
-----
-======
-
-== Default authorities for oauth2Login()
-
-In Spring Security 5, the default `GrantedAuthority` given to a user that authenticates with an OAuth2 or OpenID Connect 1.0 provider (via `oauth2Login()`) is `ROLE_USER`.
-
-In Spring Security 6, the default authority given to a user authenticating with an OAuth2 provider is `OAUTH2_USER`.
-The default authority given to a user authenticating with an OpenID Connect 1.0 provider is `OIDC_USER`.
-If you configured the `GrantedAuthoritiesMapper` only for the purpose of updating to 6.0, you can remove it completely.

+ 0 - 136
docs/modules/ROOT/pages/migration/servlet/authorization.adoc

@@ -1,136 +0,0 @@
-= Authorization Migrations
-
-The following steps relate to how to finish migrating authorization support.
-
-== Use `AuthorizationManager` for Method Security
-
-There are no further migration steps for this feature.
-
-== Use `AuthorizationManager` for Message Security
-
-In 6.0, `<websocket-message-broker>` defaults `use-authorization-manager` to `true`.
-So, to complete migration, remove any `websocket-message-broker@use-authorization-manager=true` attribute.
-
-For example:
-
-[tabs]
-======
-Xml::
-+
-[source,xml,role="primary"]
-----
-<websocket-message-broker use-authorization-manager="true"/>
-----
-======
-
-changes to:
-
-[tabs]
-======
-Xml::
-+
-[source,xml,role="primary"]
-----
-<websocket-message-broker/>
-----
-======
-
-There are no further migrations steps for Java or Kotlin for this feature.
-
-== Use `AuthorizationManager` for Request Security
-
-In 6.0, `<http>` defaults `once-per-request` to `false`, `filter-all-dispatcher-types` to `true`, and `use-authorization-manager` to `true`.
-Also, xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`.
-So, to complete migration, any defaults values can be removed.
-
-For example, if you opted in to the 6.0 default for `filter-all-dispatcher-types` or `authorizeHttpRequests#filterAllDispatcherTypes` like so:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    .authorizeHttpRequests((authorize) -> authorize
-        .filterAllDispatcherTypes(true)
-        // ...
-    )
-----
-
-Kotlin::
-+
-[source,java,role="secondary"]
-----
-http {
-	authorizeHttpRequests {
-		filterAllDispatcherTypes = true
-        // ...
-	}
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<http use-authorization-manager="true" filter-all-dispatcher-types="true"/>
-----
-======
-
-then the defaults may be removed:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-http
-    .authorizeHttpRequests((authorize) -> authorize
-        // ...
-    )
-----
-
-Kotlin::
-+
-[source,java,role="secondary"]
-----
-http {
-	authorizeHttpRequests {
-		// ...
-	}
-}
-----
-
-Xml::
-+
-[source,xml,role="secondary"]
-----
-<http/>
-----
-======
-
-[NOTE]
-====
-`once-per-request` applies only when `use-authorization-manager="false"` and `filter-all-dispatcher-types` only applies when `use-authorization-manager="true"`
-====
-
-[[compile-with-parameters]]
-=== Compile With `-parameters`
-
-Spring Framework 6.1 https://github.com/spring-projects/spring-framework/issues/29559[removes LocalVariableTableParameterNameDiscoverer].
-This affects how `@PreAuthorize` and other xref:servlet/authorization/method-security.adoc[method security] annotations will process parameter names.
-If you are using method security annotations with parameter names, for example:
-
-[source,java]
-.Method security annotation using `id` parameter name
-----
-@PreAuthorize("@authz.checkPermission(#id, authentication)")
-public void doSomething(Long id) {
-    // ...
-}
-----
-
-You must compile with `-parameters` to ensure that the parameter names are available at runtime.
-For more information about this, please visit the https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#core-container[Upgrading to Spring Framework 6.1 page].

+ 0 - 44
docs/modules/ROOT/pages/migration/servlet/exploits.adoc

@@ -1,44 +0,0 @@
-= Exploit Protection Migrations
-:spring-security-reference-base-url: https://docs.spring.io/spring-security/reference
-
-The 5.8 migration guide contains several steps for
-ifdef::spring-security-version[]
-{spring-security-reference-base-url}/5.8/migration/servlet/exploits.html[exploit protection migrations] when updating to 6.0.
-endif::[]
-ifndef::spring-security-version[]
-exploit protection migrations when updating to 6.0.
-endif::[]
-You are encouraged to follow those steps first.
-
-The following steps relate to how to finish migrating exploit protection support.
-
-== Defer Loading CsrfToken
-
-In Spring Security 5.8, the default `CsrfTokenRequestHandler` for making the `CsrfToken` available to the application is `CsrfTokenRequestAttributeHandler`.
-The default for the field `csrfRequestAttributeName` is `null`, which causes the CSRF token to be loaded on every request.
-
-In Spring Security 6, `csrfRequestAttributeName` defaults to `_csrf`.
-If you configured the following only for the purpose of updating to 6.0, you can now remove it:
-
-    requestHandler.setCsrfRequestAttributeName("_csrf");
-
-== Protect against CSRF BREACH
-
-In Spring Security 5.8, the default `CsrfTokenRequestHandler` for making the `CsrfToken` available to the application is `CsrfTokenRequestAttributeHandler`.
-`XorCsrfTokenRequestAttributeHandler` was added to allow opting into CSRF BREACH support.
-
-In Spring Security 6, `XorCsrfTokenRequestAttributeHandler` is the default `CsrfTokenRequestHandler` for making the `CsrfToken` available.
-If you configured the `XorCsrfTokenRequestAttributeHandler` only for the purpose of updating to 6.0, you can remove it completely.
-
-[NOTE]
-====
-If you have set the `csrfRequestAttributeName` to `null` in order to opt out of deferred tokens, or if you have configured a `CsrfTokenRequestHandler` for any other reason, you can leave the configuration in place.
-====
-
-== CSRF BREACH with WebSocket support
-
-In Spring Security 5.8, the default `ChannelInterceptor` for making the `CsrfToken` available with xref:servlet/integrations/websocket.adoc[WebSocket Security] is `CsrfChannelInterceptor`.
-`XorCsrfChannelInterceptor` was added to allow opting into CSRF BREACH support.
-
-In Spring Security 6, `XorCsrfChannelInterceptor` is the default `ChannelInterceptor` for making the `CsrfToken` available.
-If you configured the `XorCsrfChannelInterceptor` only for the purpose of updating to 6.0, you can remove it completely.

+ 80 - 0
docs/modules/ROOT/pages/migration/servlet/oauth2.adoc

@@ -0,0 +1,80 @@
+= OAuth 2.0 Migrations
+
+== Validate `typ` Header with `JwtTypeValidator`
+
+If when following the 6.5 preparatory steps you set `validateTypes` to `false`, you can now remove it.
+You can also remove explicitly adding `JwtTypeValidator` to the list of defaults.
+
+For example, change this:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@Bean
+JwtDecoder jwtDecoder() {
+	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
+        .validateTypes(false) <1>
+        // ... your remaining configuration
+        .build();
+	jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
+		new JwtIssuerValidator(location), JwtTypeValidator.jwt())); <2>
+	return jwtDecoder;
+}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@Bean
+fun jwtDecoder(): JwtDecoder {
+    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
+        .validateTypes(false) <1>
+        // ... your remaining configuration
+        .build()
+    jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithValidators(
+        JwtIssuerValidator(location), JwtTypeValidator.jwt())) <2>
+    return jwtDecoder
+}
+----
+======
+<1> - Switch off Nimbus verifying the `typ`
+<2> - Add the default `typ` validator
+
+to this:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@Bean
+JwtDecoder jwtDecoder() {
+	NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
+        // ... your remaining configuration <1>
+        .build();
+	jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(location)); <2>
+	return jwtDecoder;
+}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@Bean
+fun jwtDecoder(): JwtDecoder {
+    val jwtDecoder = NimbusJwtDecoder.withIssuerLocation(location)
+        // ... your remaining configuration
+        .build()
+    jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(location)) <2>
+    return jwtDecoder
+}
+----
+======
+<1> - `validateTypes` now defaults to `false`
+<2> - `JwtTypeValidator#jwt` is added by all `createDefaultXXX` methods

+ 0 - 49
docs/modules/ROOT/pages/migration/servlet/session-management.adoc

@@ -1,49 +0,0 @@
-= Session Management Migrations
-
-The following steps relate to how to finish migrating session management support.
-
-== Require Explicit Saving of SecurityContextRepository
-
-In Spring Security 5, the default behavior is for the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[`SecurityContext`] to automatically be saved to the xref:servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`] using the xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersistenceFilter`].
-Saving must be done just prior to the `HttpServletResponse` being committed and just before `SecurityContextPersistenceFilter`.
-Unfortunately, automatic persistence of the `SecurityContext` can surprise users when it is done prior to the request completing (i.e. just prior to committing the `HttpServletResponse`).
-It also is complex to keep track of the state to determine if a save is necessary causing unnecessary writes to the `SecurityContextRepository` (i.e. `HttpSession`) at times.
-
-In Spring Security 6, the default behavior is that the xref:servlet/authentication/persistence.adoc#securitycontextholderfilter[`SecurityContextHolderFilter`] will only read the `SecurityContext` from  `SecurityContextRepository` and populate it in the `SecurityContextHolder`.
-Users now must explicitly save the `SecurityContext` with the `SecurityContextRepository` if they want the `SecurityContext` to persist between requests.
-This removes ambiguity and improves performance by only requiring writing to the `SecurityContextRepository` (i.e. `HttpSession`) when it is necessary.
-
-[NOTE]
-====
-Saving the context is also needed when clearing it out, for example during logout. Refer to this section to xref:servlet/authentication/session-management.adoc#properly-clearing-authentication[know more about that].
-====
-
-If you are explicitly opting into Spring Security 6's new defaults, the following configuration can be removed to accept the Spring Security 6 defaults.
-
-
-include::partial$servlet/architecture/security-context-explicit.adoc[]
-
-== Multiple SecurityContextRepository
-
-In Spring Security 5, the default xref:servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`] was `HttpSessionSecurityContextRepository`.
-
-In Spring Security 6, the default `SecurityContextRepository` is `DelegatingSecurityContextRepository`.
-If you configured the `SecurityContextRepository` only for the purpose of updating to 6.0, you can remove it completely.
-
-== Deprecation in SecurityContextRepository
-
-There are no further migration steps for this deprecation.
-
-[[requestcache-query-optimization]]
-== Optimize Querying of `RequestCache`
-
-In Spring Security 5, the default behavior is to query the xref:servlet/architecture.adoc#savedrequests[saved request] on every request.
-This means that in a typical setup, that in order to use the xref:servlet/architecture.adoc#requestcache[`RequestCache`] the `HttpSession` is queried on every request.
-
-In Spring Security 6, the default is that `RequestCache` will only be queried for a cached request if the HTTP parameter `continue` is defined.
-This allows Spring Security to avoid unnecessarily reading the `HttpSession` with the `RequestCache`.
-
-In Spring Security 5 the default is to use `HttpSessionRequestCache` which will be queried for a cached request on every request.
-If you are not overriding the defaults (i.e. using `NullRequestCache`), then the following configuration can be used to explicitly opt into the Spring Security 6 behavior in Spring Security 5.8:
-
-include::partial$servlet/architecture/request-cache-continue.adoc[]