Security context persistence manages the storage and retrieval of authentication information between requests.
Strategy for persisting SecurityContext between requests.
package org.springframework.security.web.context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContext;
public interface SecurityContextRepository {
/**
* Loads the security context from storage.
* Deprecated - use loadDeferredContext instead.
*
* @param requestResponseHolder holder for request/response
* @return the SecurityContext
*/
@Deprecated
SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
/**
* Loads the security context as a deferred operation.
*
* @param request the HTTP request
* @return deferred SecurityContext
*/
DeferredSecurityContext loadDeferredContext(HttpServletRequest request);
/**
* Saves the security context to storage.
*
* @param context the SecurityContext to save
* @param request the HTTP request
* @param response the HTTP response
*/
void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);
/**
* Checks if a SecurityContext exists for the request.
*
* @param request the HTTP request
* @return true if context exists
*/
boolean containsContext(HttpServletRequest request);
}Stores security context in the HTTP session.
package org.springframework.security.web.context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
public class HttpSessionSecurityContextRepository implements SecurityContextRepository {
public static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
public HttpSessionSecurityContextRepository();
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
public DeferredSecurityContext loadDeferredContext(HttpServletRequest request);
public void saveContext(SecurityContext context, HttpServletRequest request,
HttpServletResponse response);
public boolean containsContext(HttpServletRequest request);
/**
* Sets whether to allow session creation (default: true).
*/
public void setAllowSessionCreation(boolean allowSessionCreation);
/**
* Sets whether to disable URL rewriting (default: true).
*/
public void setDisableUrlRewriting(boolean disableUrlRewriting);
/**
* Sets the session attribute key for the SecurityContext.
*/
public void setSpringSecurityContextKey(String springSecurityContextKey);
/**
* Sets the SecurityContextHolderStrategy.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy strategy);
}Stores security context as a request attribute (for single-request scope).
package org.springframework.security.web.context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContext;
public class RequestAttributeSecurityContextRepository implements SecurityContextRepository {
public static final String DEFAULT_REQUEST_ATTR_NAME =
"org.springframework.security.web.context.RequestAttributeSecurityContextRepository.SPRING_SECURITY_CONTEXT";
public RequestAttributeSecurityContextRepository();
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
public DeferredSecurityContext loadDeferredContext(HttpServletRequest request);
public void saveContext(SecurityContext context, HttpServletRequest request,
HttpServletResponse response);
public boolean containsContext(HttpServletRequest request);
}Delegates to multiple SecurityContextRepository implementations.
package org.springframework.security.web.context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContext;
public class DelegatingSecurityContextRepository implements SecurityContextRepository {
/**
* Creates a delegating repository.
*
* @param delegates the repositories to delegate to
*/
public DelegatingSecurityContextRepository(SecurityContextRepository... delegates);
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
public DeferredSecurityContext loadDeferredContext(HttpServletRequest request);
public void saveContext(SecurityContext context, HttpServletRequest request,
HttpServletResponse response);
public boolean containsContext(HttpServletRequest request);
}A SecurityContextRepository that does not persist context (stateless).
package org.springframework.security.web.context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.context.SecurityContext;
public class NullSecurityContextRepository implements SecurityContextRepository {
public NullSecurityContextRepository();
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
public DeferredSecurityContext loadDeferredContext(HttpServletRequest request);
public void saveContext(SecurityContext context, HttpServletRequest request,
HttpServletResponse response);
public boolean containsContext(HttpServletRequest request);
}Loads and stores SecurityContext using SecurityContextRepository.
package org.springframework.security.web.context;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.web.filter.OncePerRequestFilter;
public class SecurityContextHolderFilter extends OncePerRequestFilter {
/**
* Creates a filter with the given repository.
*
* @param securityContextRepository the repository to use
*/
public SecurityContextHolderFilter(SecurityContextRepository securityContextRepository);
protected void doFilterInternal(ServletRequest request, ServletResponse response,
FilterChain chain)
throws ServletException, IOException;
/**
* Sets the SecurityContextHolderStrategy.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy);
}Populates SecurityContextHolder and saves context after request completes. Deprecated in favor of SecurityContextHolderFilter.
package org.springframework.security.web.context;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.web.filter.GenericFilterBean;
@Deprecated
public class SecurityContextPersistenceFilter extends GenericFilterBean {
/**
* Creates a filter with HttpSessionSecurityContextRepository.
*/
public SecurityContextPersistenceFilter();
/**
* Creates a filter with the given repository.
*/
public SecurityContextPersistenceFilter(SecurityContextRepository securityContextRepository);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
/**
* Forces eager session creation (default: false).
*/
public void setForceEagerSessionCreation(boolean forceEagerSessionCreation);
/**
* Sets the SecurityContextHolderStrategy.
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy);
}Represents a SecurityContext that may be loaded lazily.
package org.springframework.security.web.context;
import java.util.function.Supplier;
import org.springframework.security.core.context.SecurityContext;
public interface DeferredSecurityContext extends Supplier<SecurityContext> {
/**
* Gets the SecurityContext, loading it if necessary.
*
* @return the SecurityContext
*/
SecurityContext get();
/**
* Returns true if the context has been generated.
*
* @return true if generated
*/
boolean isGenerated();
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
@Configuration
public class SecurityContextConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityContext(context -> context
.securityContextRepository(securityContextRepository())
);
return http.build();
}
@Bean
public SecurityContextRepository securityContextRepository() {
return new HttpSessionSecurityContextRepository();
}
}import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class StatelessConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.securityContext(context -> context
.securityContextRepository(new NullSecurityContextRepository())
);
return http.build();
}
}import org.springframework.context.annotation.Bean;
import org.springframework.security.web.context.DelegatingSecurityContextRepository;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
@Configuration
public class HybridContextConfig {
@Bean
public SecurityContextRepository securityContextRepository() {
return new DelegatingSecurityContextRepository(
new RequestAttributeSecurityContextRepository(),
new HttpSessionSecurityContextRepository()
);
}
}import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.SecurityContextRepository;
@Service
public class AuthenticationService {
private final SecurityContextRepository securityContextRepository;
public AuthenticationService(SecurityContextRepository securityContextRepository) {
this.securityContextRepository = securityContextRepository;
}
public void authenticateAndSaveContext(Authentication authentication,
HttpServletRequest request,
HttpServletResponse response) {
// Create and set security context
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
// Explicitly save to repository
securityContextRepository.saveContext(context, request, response);
}
}