mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	SEC-1396: Implement eager saving of SecurityContext in SessionManagementFilter on authentication.
The user is then seen as being authenticated to further (re-entrant) requests which occur before the existing request has completed. The saving logic is contained with the SecurityContextRepository implementation.
This commit is contained in:
		
							parent
							
								
									403f8da79a
								
							
						
					
					
						commit
						dcbdfc2026
					
				| @ -36,6 +36,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio | ||||
| import org.springframework.security.config.BeanIds; | ||||
| import org.springframework.security.config.PostProcessedMockUserDetailsService; | ||||
| import org.springframework.security.config.util.InMemoryXmlApplicationContext; | ||||
| import org.springframework.security.core.context.SecurityContext; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.core.session.SessionRegistryImpl; | ||||
| import org.springframework.security.openid.OpenID4JavaConsumer; | ||||
| @ -77,6 +78,7 @@ import org.springframework.security.web.authentication.rememberme.TokenBasedReme | ||||
| import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; | ||||
| import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; | ||||
| import org.springframework.security.web.context.HttpSessionSecurityContextRepository; | ||||
| import org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper; | ||||
| import org.springframework.security.web.context.SecurityContextPersistenceFilter; | ||||
| import org.springframework.security.web.savedrequest.HttpSessionRequestCache; | ||||
| import org.springframework.security.web.savedrequest.RequestCacheAwareFilter; | ||||
| @ -790,13 +792,17 @@ public class HttpSecurityBeanDefinitionParserTests { | ||||
|         // Register 2 sessions and then check a third | ||||
| //        req.setSession(new MockHttpSession()); | ||||
| //        auth.setDetails(new WebAuthenticationDetails(req)); | ||||
|         MockHttpServletResponse response = new MockHttpServletResponse(); | ||||
|         MockHttpServletResponse mockResponse = new MockHttpServletResponse(); | ||||
|         SaveContextOnUpdateOrErrorResponseWrapper response = new SaveContextOnUpdateOrErrorResponseWrapper(mockResponse, false) { | ||||
|             protected void saveContext(SecurityContext context) { | ||||
|             } | ||||
|         }; | ||||
|         seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); | ||||
|         assertNull(response.getRedirectedUrl()); | ||||
|         assertNull(mockResponse.getRedirectedUrl()); | ||||
|         seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); | ||||
|         assertNull(response.getRedirectedUrl()); | ||||
|         assertNull(mockResponse.getRedirectedUrl()); | ||||
|         seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); | ||||
|         assertEquals("/max-exceeded", response.getRedirectedUrl()); | ||||
|         assertEquals("/max-exceeded", mockResponse.getRedirectedUrl()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|  | ||||
| @ -98,7 +98,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo | ||||
|     } | ||||
| 
 | ||||
|     public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) { | ||||
|         SaveToSessionResponseWrapper responseWrapper = (SaveToSessionResponseWrapper)response; | ||||
|         SaveContextOnUpdateOrErrorResponseWrapper responseWrapper = (SaveContextOnUpdateOrErrorResponseWrapper)response; | ||||
|         // saveContext() might already be called by the response wrapper | ||||
|         // if something in the chain called sendError() or sendRedirect(). This ensures we only call it | ||||
|         // once per request. | ||||
| @ -289,7 +289,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo | ||||
|      * Stores the necessary state from the start of the request in order to make a decision about whether | ||||
|      * the security context has changed before saving it. | ||||
|      */ | ||||
|     class SaveToSessionResponseWrapper extends SaveContextOnUpdateOrErrorResponseWrapper { | ||||
|     final class SaveToSessionResponseWrapper extends SaveContextOnUpdateOrErrorResponseWrapper { | ||||
| 
 | ||||
|         private HttpServletRequest request; | ||||
|         private boolean httpSessionExistedAtStartOfRequest; | ||||
| @ -327,7 +327,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo | ||||
|          * | ||||
|          */ | ||||
|         @Override | ||||
|         void saveContext(SecurityContext context) { | ||||
|         protected void saveContext(SecurityContext context) { | ||||
|             // See SEC-776 | ||||
|             if (authenticationTrustResolver.isAnonymous(context.getAuthentication())) { | ||||
|                 if (logger.isDebugEnabled()) { | ||||
|  | ||||
| @ -42,7 +42,7 @@ public abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServ | ||||
|      * | ||||
|      * @param context the <tt>SecurityContext</tt> instance to store | ||||
|      */ | ||||
|     abstract void saveContext(SecurityContext context); | ||||
|     protected abstract void saveContext(SecurityContext context); | ||||
| 
 | ||||
|     /** | ||||
|      * Makes sure the session is updated before calling the | ||||
|  | ||||
| @ -78,6 +78,9 @@ public class SessionManagementFilter extends GenericFilterBean { | ||||
| 
 | ||||
|                     return; | ||||
|                 } | ||||
|                 // Eagerly save the security context to make it available for any possible re-entrant | ||||
|                 // requests which may occur before the current request completes. SEC-1396. | ||||
|                 securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response); | ||||
|             } else { | ||||
|              // No security context or authentication present. Check for a session timeout | ||||
|                 if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user