Merge branch '5.8.x' into 6.0.x

Closes gh-12941
This commit is contained in:
Marcus Da Coregio 2023-03-28 15:23:21 -03:00
commit b4b4cd0ffa
3 changed files with 40 additions and 6 deletions

View File

@ -13,8 +13,14 @@ In Spring Security 6, the default behavior is that the xref:servlet/authenticati
Users now must explicitly save the `SecurityContext` with the `SecurityContextRepository` if they want the `SecurityContext` to persist between requests. 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. 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. 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[] include::partial$servlet/architecture/security-context-explicit.adoc[]
== Multiple SecurityContextRepository == Multiple SecurityContextRepository

View File

@ -141,6 +141,7 @@ If not configured, a status code 200 is returned by default.
[[jc-logout-references]] [[jc-logout-references]]
== Further Logout-Related References == Further Logout-Related References
- xref:servlet/authentication/session-management.adoc#properly-clearing-authentication[Properly Clearing Authentication When Explicit Save Is Enabled]
- <<ns-logout, Logout Handling>> - <<ns-logout, Logout Handling>>
- xref:servlet/test/mockmvc/logout.adoc#test-logout[Testing Logout] - xref:servlet/test/mockmvc/logout.adoc#test-logout[Testing Logout]
- xref:servlet/integrations/servlet-api.adoc#servletapi-logout[`HttpServletRequest.logout()`] - xref:servlet/integrations/servlet-api.adoc#servletapi-logout[`HttpServletRequest.logout()`]

View File

@ -12,6 +12,7 @@ But before you leave, consider if any of these use cases fit your application:
* I want to <<understanding-session-management-components,Understand Session Management's components>> * I want to <<understanding-session-management-components,Understand Session Management's components>>
* I want to <<ns-concurrent-sessions,restrict the number of times>> a user can be logged in concurrently * I want to <<ns-concurrent-sessions,restrict the number of times>> a user can be logged in concurrently
* I want <<store-authentication-manually,to store the authentication directly>> myself instead of Spring Security doing it for me * I want <<store-authentication-manually,to store the authentication directly>> myself instead of Spring Security doing it for me
* I am storing the authentication manually and I want <<properly-clearing-authentication,to remove it>>
* I am using <<the-sessionmanagementfilter, `SessionManagementFilter`>> and I need <<moving-away-from-sessionmanagementfilter,guidance on moving away from that>> * I am using <<the-sessionmanagementfilter, `SessionManagementFilter`>> and I need <<moving-away-from-sessionmanagementfilter,guidance on moving away from that>>
* I want to store the authentication <<customizing-where-authentication-is-stored,in something other than the session>> * I want to store the authentication <<customizing-where-authentication-is-stored,in something other than the session>>
* I am using a <<stateless-authentication, stateless authentication>>, but <<storing-stateless-authentication-in-the-session,I'd still like to store it in the session>> * I am using a <<stateless-authentication, stateless authentication>>, but <<storing-stateless-authentication-in-the-session,I'd still like to store it in the session>>
@ -84,12 +85,6 @@ By default, Spring Security stores the security context for you in the HTTP sess
First, you need to create an implementation of `SecurityContextRepository` or use an existing implementation like `HttpSessionSecurityContextRepository`, then you can set it in `HttpSecurity`. First, you need to create an implementation of `SecurityContextRepository` or use an existing implementation like `HttpSessionSecurityContextRepository`, then you can set it in `HttpSecurity`.
[NOTE]
====
The above configuration sets the `SecurityContextRepository` on the `SecurityContextHolderFilter` and **participating** authentication filters, like `UsernamePasswordAuthenticationFilter`.
To also set it in stateless filters, please see <<storing-stateless-authentication-in-the-session,how to customize the `SecurityContextRepository` for Stateless Authentication>>.
====
[[customizing-the-securitycontextrepository]] [[customizing-the-securitycontextrepository]]
.Customizing the `SecurityContextRepository` .Customizing the `SecurityContextRepository`
==== ====
@ -134,6 +129,12 @@ open fun filterChain(http: HttpSecurity): SecurityFilterChain {
---- ----
==== ====
[NOTE]
====
The above configuration sets the `SecurityContextRepository` on the `SecurityContextHolderFilter` and **participating** authentication filters, like `UsernamePasswordAuthenticationFilter`.
To also set it in stateless filters, please see <<storing-stateless-authentication-in-the-session,how to customize the `SecurityContextRepository` for Stateless Authentication>>.
====
If you are using a custom authentication mechanism, you might want to <<store-authentication-manually,store the `Authentication` by yourself>>. If you are using a custom authentication mechanism, you might want to <<store-authentication-manually,store the `Authentication` by yourself>>.
[[store-authentication-manually]] [[store-authentication-manually]]
@ -181,6 +182,32 @@ class LoginRequest {
And that's it. And that's it.
If you are not sure what `securityContextHolderStrategy` is in the above example, you can read more about it in the <<use-securitycontextholderstrategy, Using `SecurityContextStrategy` section>>. If you are not sure what `securityContextHolderStrategy` is in the above example, you can read more about it in the <<use-securitycontextholderstrategy, Using `SecurityContextStrategy` section>>.
[[properly-clearing-authentication]]
=== Properly Clearing an Authentication
If you are using Spring Security's xref:servlet/authentication/logout.adoc[Logout Support] then it handles a lot of stuff for you including clearing and saving the context.
But, let's say you need to manually log users out of your app. In that case, you'll need to make sure you're clearing and saving the context properly.
Now, you might already be familiar with clearing the `SecurityContextHolder` by doing `SecurityContextHolderStrategy#clearContext()`.
That's great, but if your app requires an xref:migration/servlet/session-management.adoc#_require_explicit_saving_of_securitycontextrepository[explicit save of the context], simply clearing it isn't enough.
The reason is that it doesn't remove it from the `SecurityContextRepository`, which means the `SecurityContext` could still be available for the next requests, and we definitely don't want that.
To make sure the authentication is properly cleared and saved, you can invoke {security-api-url}/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.html[the `SecurityContextLogoutHandler`] which does that for us, like so:
====
.Java
[source,java,role="primary"]
----
SecurityContextLogoutHandler handler = new SecurityContextLogoutHandler(); <1>
handler.logout(httpServletRequest, httpServletResponse, null); <2>
----
====
<1> Create a new instance of `SecurityContextLogoutHandler`
<2> Call the `logout` method passing in the `HttpServletRequest`, `HttpServletResponse` and a `null` authentication because it is not required for this handler.
It's important to remember that clearing and saving the context is just one piece of the logout process, therefore we recommend having Spring Security take care of it.
[[stateless-authentication]] [[stateless-authentication]]
=== Configuring Persistence for Stateless Authentication === Configuring Persistence for Stateless Authentication