mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-03-03 20:09:18 +00:00
Document Migration to SecurityContextHolderFilter
Closes gh-12098
This commit is contained in:
parent
1dd13e69a4
commit
aac1261f0c
@ -13,6 +13,21 @@ endif::[]
|
|||||||
|
|
||||||
== Servlet
|
== Servlet
|
||||||
|
|
||||||
|
=== Explicit Save 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.
|
||||||
|
|
||||||
|
To opt into the new Spring Security 6 default, the following configuration can be used.
|
||||||
|
|
||||||
|
include::partial$servlet/architecture/security-context-explicit.adoc[]
|
||||||
|
|
||||||
[[requestcache-query-optimization]]
|
[[requestcache-query-optimization]]
|
||||||
=== Optimize Querying of `RequestCache`
|
=== Optimize Querying of `RequestCache`
|
||||||
|
|
||||||
|
@ -144,29 +144,8 @@ image::{figures}/securitycontextholderfilter.png[]
|
|||||||
<1> Before running the rest of the application, `SecurityContextHolderFilter` loads the `SecurityContext` from the `SecurityContextRepository` and sets it on the `SecurityContextHolder`.
|
<1> Before running the rest of the application, `SecurityContextHolderFilter` loads the `SecurityContext` from the `SecurityContextRepository` and sets it on the `SecurityContextHolder`.
|
||||||
<2> Next, the application is ran.
|
<2> Next, the application is ran.
|
||||||
|
|
||||||
Unlike, xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersisteneFilter`], `SecurityContextHolderFilter` only loads the `SecurityContext` it does not save the `SecurityContext`.
|
Unlike, xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersistenceFilter`], `SecurityContextHolderFilter` only loads the `SecurityContext` it does not save the `SecurityContext`.
|
||||||
This means that when using `SecurityContextHolderFilter`, it is required that the `SecurityContext` is explicitly saved.
|
This means that when using `SecurityContextHolderFilter`, it is required that the `SecurityContext` is explicitly saved.
|
||||||
|
|
||||||
.Explicit Saving of SecurityContext
|
|
||||||
====
|
|
||||||
.Java
|
|
||||||
[source,java,role="primary"]
|
|
||||||
----
|
|
||||||
public SecurityFilterChain filterChain(HttpSecurity http) {
|
|
||||||
http
|
|
||||||
// ...
|
|
||||||
.securityContext((securityContext) -> securityContext
|
|
||||||
.requireExplicitSave(true)
|
|
||||||
);
|
|
||||||
return http.build();
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
.XML
|
include::partial$servlet/architecture/security-context-explicit.adoc[]
|
||||||
[source,xml,role="secondary"]
|
|
||||||
----
|
|
||||||
<http security-context-explicit-save="true">
|
|
||||||
<!-- ... -->
|
|
||||||
</http>
|
|
||||||
----
|
|
||||||
====
|
|
@ -0,0 +1,76 @@
|
|||||||
|
.Explicit Saving of SecurityContext
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) {
|
||||||
|
http
|
||||||
|
// ...
|
||||||
|
.securityContext((securityContext) -> securityContext
|
||||||
|
.requireExplicitSave(true)
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
http {
|
||||||
|
securityContext {
|
||||||
|
requireExplicitSave = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return http.build()
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.XML
|
||||||
|
[source,xml,role="secondary"]
|
||||||
|
----
|
||||||
|
<http security-context-explicit-save="true">
|
||||||
|
<!-- ... -->
|
||||||
|
</http>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
Upon using the configuration, it is important that any code that sets the `SecurityContextHolder` with a `SecurityContext` also saves the `SecurityContext` to the `SecurityContextRepository` if it should be persisted between requests.
|
||||||
|
|
||||||
|
For example, the following code:
|
||||||
|
|
||||||
|
.Setting `SecurityContextHolder` with `SecurityContextPersistenceFilter`
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
SecurityContextHolder.setContext(securityContext);
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
SecurityContextHolder.setContext(securityContext)
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
should be replaced with
|
||||||
|
|
||||||
|
.Setting `SecurityContextHolder` with `SecurityContextHolderFilter`
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
SecurityContextHolder.setContext(securityContext);
|
||||||
|
securityContextRepository.saveContext(securityContext, httpServletRequest, httpServletResponse);
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
SecurityContextHolder.setContext(securityContext)
|
||||||
|
securityContextRepository.saveContext(securityContext, httpServletRequest, httpServletResponse)
|
||||||
|
----
|
||||||
|
====
|
Loading…
x
Reference in New Issue
Block a user