Преглед изворни кода

Merge branch '5.8.x'

Closes gh-12091
Closes gh-12092
Rob Winch пре 2 година
родитељ
комит
d40ed58118

+ 14 - 0
docs/modules/ROOT/pages/migration.adoc

@@ -10,6 +10,20 @@ Also, this guide includes ways to <<revert,revert to 5.x>> behaviors and its def
 
 
 == Servlet
 == Servlet
 
 
+[[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[]
+
 === Use `AuthorizationManager` for Method Security
 === Use `AuthorizationManager` for Method Security
 
 
 There are no further migration steps for this feature.
 There are no further migration steps for this feature.

+ 26 - 3
docs/modules/ROOT/pages/servlet/architecture.adoc

@@ -189,7 +189,7 @@ The following is a comprehensive list of Spring Security Filter ordering:
 * xref:servlet/authentication/passwords/digest.adoc#servlet-authentication-digest[`DigestAuthenticationFilter`]
 * xref:servlet/authentication/passwords/digest.adoc#servlet-authentication-digest[`DigestAuthenticationFilter`]
 * `BearerTokenAuthenticationFilter`
 * `BearerTokenAuthenticationFilter`
 * xref:servlet/authentication/passwords/basic.adoc#servlet-authentication-basic[`BasicAuthenticationFilter`]
 * xref:servlet/authentication/passwords/basic.adoc#servlet-authentication-basic[`BasicAuthenticationFilter`]
-* `RequestCacheAwareFilter`
+* <<requestcacheawarefilter,RequestCacheAwareFilter>>
 * `SecurityContextHolderAwareRequestFilter`
 * `SecurityContextHolderAwareRequestFilter`
 * `JaasApiIntegrationFilter`
 * `JaasApiIntegrationFilter`
 * `RememberMeAuthenticationFilter`
 * `RememberMeAuthenticationFilter`
@@ -216,8 +216,8 @@ image::{figures}/exceptiontranslationfilter.png[]
 * image:{icondir}/number_1.png[] First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.
 * image:{icondir}/number_1.png[] First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.
 * image:{icondir}/number_2.png[] If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
 * image:{icondir}/number_2.png[] If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
 ** The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out.
 ** The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out.
-** The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
-When the user successfully authenticates, the `RequestCache` is used to replay the original request.
+** The `HttpServletRequest` is <<savedrequests,saved>> so that it can be used to replay the original request once authentication is successful.
+
 // FIXME: add link to authentication success
 // FIXME: add link to authentication success
 ** The `AuthenticationEntryPoint` is used to request credentials from the client.
 ** The `AuthenticationEntryPoint` is used to request credentials from the client.
 For example, it might redirect to a log in page or send a `WWW-Authenticate` header.
 For example, it might redirect to a log in page or send a `WWW-Authenticate` header.
@@ -252,3 +252,26 @@ This means that if another part of the application, (<<servlet-authorization-fil
 <2> If the user is not authenticated or it is an `AuthenticationException`, __Start Authentication__.
 <2> If the user is not authenticated or it is an `AuthenticationException`, __Start Authentication__.
 <3> Otherwise, __Access Denied__
 <3> Otherwise, __Access Denied__
 ====
 ====
+
+[[savedrequests]]
+== Saving Requests Between Authentication
+
+As illustrated in <<servlet-exceptiontranslationfilter>>, when a request has no authentication and is for a resource that requires authentication, there is a need to save the request for the authenticated resource to re-request after authentication is successful.
+In Spring Security this is done by saving the `HttpServletRequest` using a <<requestcache,`RequestCache`>> implementation.
+
+[[requestcache]]
+=== RequestCache
+
+The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
+When the user successfully authenticates, the `RequestCache` is used to replay the original request.
+The <<requestcacheawarefilter,`RequestCacheAwareFilter`>> is what uses the `RequestCache` to save the `HttpServletRequest`.
+
+By default, an `HttpSessionRequestCache` is used.
+The code below demonstrates how to customize the `RequestCache` implementation that is used to check the `HttpSession` for a saved request if the parameter named `continue` is present.
+
+include::partial$servlet/architecture/request-cache-continue.adoc[]
+
+[[requestcacheawarefilter]]
+=== RequestCacheAwareFilter
+
+The {security-api-url}org/springframework/security/web/savedrequest/RequestCacheAwareFilter.html[`RequestCacheAwareFilter`] uses the <<requestcache,`RequestCache`>> to save the `HttpServletRequest`.

+ 50 - 0
docs/modules/ROOT/partials/servlet/architecture/request-cache-continue.adoc

@@ -0,0 +1,50 @@
+.`RequestCache` Only Checks for Saved Requests if `continue` Parameter Present
+====
+.Java
+[source,java,role="primary"]
+----
+@Bean
+DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
+	HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
+	requestCache.setMatchingRequestParameterName("continue");
+	http
+		// ...
+		.requestCache((cache) -> cache
+			.requestCache(requestCache)
+		);
+	return http.build();
+}
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@EnableWebSecurity
+class SecurityConfig {
+
+	@Bean
+	open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
+		val httpRequestCache = HttpSessionRequestCache()
+		httpRequestCache.setMatchingRequestParameterName("continue")
+		http {
+			requestCache {
+				requestCache = httpRequestCache
+			}
+		}
+		return http.build()
+	}
+}
+----
+
+.XML
+[source,xml,role="secondary"]
+----
+<http auto-config="true">
+	<!-- ... -->
+	<request-cache ref="requestCache"/>
+</http>
+
+<b:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"
+	p:matchingRequestParameterName="continue"/>
+----
+====