Skip to content

Commit c17e258

Browse files
committed
Document Saved Requests
Closes gh-12088
1 parent f6731e8 commit c17e258

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

docs/modules/ROOT/pages/servlet/architecture.adoc

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ Below is a comprehensive list of Spring Security Filter ordering:
188188
* xref:servlet/authentication/passwords/digest.adoc#servlet-authentication-digest[`DigestAuthenticationFilter`]
189189
* BearerTokenAuthenticationFilter
190190
* xref:servlet/authentication/passwords/basic.adoc#servlet-authentication-basic[`BasicAuthenticationFilter`]
191-
* RequestCacheAwareFilter
191+
* <<requestcacheawarefilter,RequestCacheAwareFilter>>
192192
* SecurityContextHolderAwareRequestFilter
193193
* JaasApiIntegrationFilter
194194
* RememberMeAuthenticationFilter
@@ -213,8 +213,7 @@ image::{figures}/exceptiontranslationfilter.png[]
213213
* image:{icondir}/number_1.png[] First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.
214214
* image:{icondir}/number_2.png[] If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
215215
** The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out
216-
** The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
217-
When the user successfully authenticates, the `RequestCache` is used to replay the original request.
216+
** The `HttpServletRequest` is <<savedrequests,saved>> so that it can be used to replay the original request once authentication is successful.
218217
// FIXME: add link to authentication success
219218
** The `AuthenticationEntryPoint` is used to request credentials from the client.
220219
For example, it might redirect to a log in page or send a `WWW-Authenticate` header.
@@ -247,3 +246,26 @@ try {
247246
This means that if another part of the application, (i.e. xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] or method security) throws an `AuthenticationException` or `AccessDeniedException` it will be caught and handled here.
248247
<2> If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
249248
<3> Otherwise, __Access Denied__
249+
250+
[[savedrequests]]
251+
== Saving Requests Between Authentication
252+
253+
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.
254+
In Spring Security this is done by saving the `HttpServletRequest` using a <<requestcache,`RequestCache`>> implementation.
255+
256+
[[requestcache]]
257+
=== RequestCache
258+
259+
The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
260+
When the user successfully authenticates, the `RequestCache` is used to replay the original request.
261+
The <<requestcacheawarefilter,`RequestCacheAwareFilter`>> is what uses the `RequestCache` to save the `HttpServletRequest`.
262+
263+
By default, an `HttpSessionRequestCache` is used.
264+
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.
265+
266+
include::partial$servlet/architecture/request-cache-continue.adoc[]
267+
268+
[[requestcacheawarefilter]]
269+
=== RequestCacheAwareFilter
270+
271+
The {security-api-url}org/springframework/security/web/savedrequest/RequestCacheAwareFilter.html[`RequestCacheAwareFilter`] uses the <<requestcache,`RequestCache`>> to save the `HttpServletRequest`.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
.`RequestCache` Only Checks for Saved Requests if `continue` Parameter Present
2+
====
3+
.Java
4+
[source,java,role="primary"]
5+
----
6+
@Bean
7+
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
8+
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
9+
requestCache.setMatchingRequestParameterName("continue");
10+
http
11+
// ...
12+
.requestCache((cache) -> cache
13+
.requestCache(requestCache)
14+
);
15+
return http.build();
16+
}
17+
----
18+
19+
.Kotlin
20+
[source,kotlin,role="secondary"]
21+
----
22+
@EnableWebSecurity
23+
class SecurityConfig {
24+
25+
@Bean
26+
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
27+
val httpRequestCache = HttpSessionRequestCache()
28+
httpRequestCache.setMatchingRequestParameterName("continue")
29+
http {
30+
requestCache {
31+
requestCache = httpRequestCache
32+
}
33+
}
34+
return http.build()
35+
}
36+
}
37+
----
38+
39+
.XML
40+
[source,xml,role="secondary"]
41+
----
42+
<http auto-config="true">
43+
<!-- ... -->
44+
<request-cache ref="requestCache"/>
45+
</http>
46+
47+
<b:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"
48+
p:matchingRequestParameterName="continue"/>
49+
----
50+
====

0 commit comments

Comments
 (0)