Improve Docs by mentioning that Empty SecurityContext should be saved
Closes gh-12906
This commit is contained in:
		
							parent
							
								
									c15589ede1
								
							
						
					
					
						commit
						eb58655fa9
					
				| 
						 | 
					@ -11,6 +11,11 @@ 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].
 | 
				
			||||||
 | 
					====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To opt into the new Spring Security 6 default, the following configuration can be used.
 | 
					To opt into the new Spring Security 6 default, the following configuration can be used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include::partial$servlet/architecture/security-context-explicit.adoc[]
 | 
					include::partial$servlet/architecture/security-context-explicit.adoc[]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,6 +139,7 @@ If not configured a status code 200 will be 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()]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,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>>
 | 
				
			||||||
| 
						 | 
					@ -168,12 +169,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`
 | 
				
			||||||
====
 | 
					====
 | 
				
			||||||
| 
						 | 
					@ -220,6 +215,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]]
 | 
				
			||||||
| 
						 | 
					@ -267,6 +268,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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue