skip to content

Explain SessionCreationPolicy STATELESS vs IF_REQUIRED and when you would choose each.

level: middleimportance: must knowfreq 70%

answer

  1. IF_REQUIRED = default, lazy session for SecurityContext
  2. STATELESS = never create/use session, re-auth every request
  3. ALWAYS / IF_REQUIRED / NEVER / STATELESS
  4. STATELESS needs a per-request token filter
  5. only governs Spring Security's own session use

basics

~20 s

IF_REQUIRED (the default) lets Spring create an HttpSession only when needed, e.g. to remember a logged-in user. STATELESS never creates or uses a session — each request must carry its own credentials, typical for token/JWT APIs.

solid answer

~40 s

SessionCreationPolicy controls whether Spring Security will create/use an HttpSession. IF_REQUIRED is the default: Spring creates a session lazily when it needs one — mainly to persist the SecurityContext across requests via HttpSessionSecurityContextRepository — so a browser form-login flow stays authenticated. STATELESS tells Spring Security to never create a session and never read the SecurityContext from one; every request is authenticated from scratch, usually by a bearer-token/JWT filter that populates the SecurityContextHolder per request. Choose IF_REQUIRED for classic server-rendered web apps with cookie sessions. Choose STATELESS for horizontally scaled REST APIs where you don't want server-side session affinity and instead carry identity in a self-contained token. Note STATELESS only governs Spring Security's own session use — application code or other filters can still create sessions unless you also prevent that.

code

java · 11 lines
java
@Bean
SecurityFilterChain api(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())            // typical for token APIs
        .authorizeHttpRequests(a -> a.anyRequest().authenticated())
        .sessionManagement(s -> s
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()));
    // each request re-authenticated from the Bearer JWT; no HttpSession
    return http.build();
}

go deeper

for a junior

Know the default is IF_REQUIRED and STATELESS means no session / token per request.

for a middle

List all four policies and connect IF_REQUIRED to HttpSessionSecurityContextRepository.

for a senior

Explain per-request context clearing under STATELESS, the NEVER vs STATELESS nuance, and CSRF/flash-attribute session leaks.

for a principal

Weigh session affinity vs shared session store vs stateless tokens for horizontal scale, and the security/ops trade-offs (revocation, token size, replication).

**What it configures.** `SessionCreationPolicy` is an enum passed to `http.sessionManagement(s -> s.sessionCreationPolicy(...))`. It tells Spring Security *when it may create or use an `HttpSession`*. The four values: - **`ALWAYS`** — a session is created if one doesn't exist, even when Spring Security doesn't strictly need it. - **`IF_REQUIRED`** — **the default** — a session is created only when required (e.g. to store the `SecurityContext` after login, or for CSRF token storage). Lazy. - **`NEVER`** — Spring Security will not *create* a session, but *will use* one if it already exists (created by other code). - **`STATELESS`** — Spring Security will neither create nor use an `HttpSession`; the `SecurityContext` is never loaded from or saved to a session. **Why sessions matter here.** After a successful login the `SecurityContext` (holding the `Authentication`) must survive to the next request. In a stateful app that is done by `HttpSessionSecurityContextRepository`, which stores the context under a session attribute (`SPRING_SECURITY_CONTEXT`). That storage *requires* an `HttpSession`, which is why IF_REQUIRED ends up creating one after login. **IF_REQUIRED — the stateful path.** - Ideal for server-rendered web apps (Thymeleaf, MVC) using form login and the `JSESSIONID` cookie. - The user authenticates once; subsequent requests are recognized because the context is reloaded from the session. - Sessions imply server-side state → sticky sessions or a shared store (Spring Session + Redis) when scaling horizontally. **STATELESS — the token path.** - Ideal for REST APIs / microservices. Identity travels in each request (typically a JWT `Authorization: Bearer` header validated by a filter such as `BearerTokenAuthenticationFilter` in a resource server, or a custom filter). - No server-side session → trivial horizontal scaling, no session replication, but the SecurityContext is discarded at the end of each request (`SecurityContextHolder.clearContext()` per request). - With STATELESS, the effective `SecurityContextRepository` does not persist to a session, so even if you call `SecurityContextHolder.getContext().setAuthentication(...)` it will not survive to the next request. **Gotchas.** - STATELESS only stops *Spring Security* from touching sessions. If your controllers call `request.getSession()`, or if Spring MVC creates one for flash attributes, a session can still appear. To be truly stateless, avoid those and often disable CSRF (which by default stores a token server-side) or use a stateless CSRF token repository. - Under STATELESS, session-fixation protection and concurrent-session control are irrelevant (nothing to protect). - `NEVER` is subtly different from `STATELESS`: NEVER will still read an existing session, so a stray session could still supply a SecurityContext. Prefer STATELESS for real token APIs. - Setting STATELESS does not by itself authenticate anyone — you must add the token/authentication filter that populates the context each request. **When to use which.** Cookie/session browser app → IF_REQUIRED (the default). Token-secured API that must scale without session affinity → STATELESS plus a per-request authentication filter.

  • If you set STATELESS but a controller calls request.getSession(), does a session get created?
    Yes. STATELESS only prevents Spring Security from creating/using a session. Application code (or MVC features) can still create one; you must avoid those calls to stay truly stateless.
  • How does NEVER differ from STATELESS?
    NEVER won't create a session but will still read/use an existing one (so a stray session could supply a SecurityContext). STATELESS neither creates nor reads a session for the SecurityContext.

saying these in an interview costs you the question

  • Saying STATELESS guarantees no HttpSession can ever exist in the app (it only stops Spring Security from making one).
  • Thinking STATELESS by itself authenticates requests without an added token filter.
  • Confusing NEVER and STATELESS as identical.

context