skip to content

Authentication

Proving who the caller is: the manager and provider chain, user details and password storage, form and basic login, anonymous authentication, events and logout. Interviewers walk this path because a custom authentication mechanism is a common real-world task.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

What does formLogin() enable in Spring Security, and what is the role of UsernamePasswordAuthenticationFilter?

level: juniorimportance: must knowfreq 80%

answer

  1. formLogin -> UsernamePasswordAuthenticationFilter
  2. POST /login reads username/password params
  3. builds unauthenticated UsernamePasswordAuthenticationToken
  4. AuthenticationManager verifies; stored in session (stateful)
  5. SavedRequest success handler, /login?error on failure

basics

~10 s

formLogin() turns on a browser login form. Spring adds UsernamePasswordAuthenticationFilter, which intercepts the POST to /login, reads the username and password fields, and asks the AuthenticationManager to verify them.

solid answer

~40 s

formLogin() configures form-based authentication for browser clients. It registers UsernamePasswordAuthenticationFilter, which by default intercepts POST /login, extracts the 'username' and 'password' request parameters, wraps them in an unauthenticated UsernamePasswordAuthenticationToken, and hands it to the AuthenticationManager. On success the resulting authenticated token is stored in the SecurityContext (persisted in the HTTP session via SecurityContextRepository) and the SavedRequestAwareAuthenticationSuccessHandler redirects to the originally requested URL. On failure it redirects to /login?error. GET /login renders a default auto-generated form unless you specify a custom loginPage. Form login is stateful — subsequent requests are recognized by the session, not re-sent credentials. It is the standard choice for server-rendered web apps.

code

java · 19 lines
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/login", "/css/**").permitAll()
                .anyRequest().authenticated())
            .formLogin(form -> form
                .loginPage("/login")            // custom GET page
                .loginProcessingUrl("/login")   // POST target for the form
                .usernameParameter("email")     // rename the field
                .defaultSuccessUrl("/dashboard", true)
                .failureUrl("/login?error"));
        return http.build();
    }
}

go deeper

for a junior

Know that formLogin() gives a login form and that a filter checks username/password against the AuthenticationManager.

for a middle

Explain the token flow, default success/failure handlers, and that state lives in the session via SecurityContextRepository.

for a senior

Discuss customizing loginProcessingUrl, parameter names, handlers, and the CSRF/saved-request interactions.

for a principal

Reason about when form login is the wrong fit (stateless APIs), session-fixation protection, and coexistence with other auth mechanisms in one filter chain.

## What formLogin() is `formLogin()` is a DSL method on `HttpSecurity` (Spring Security's Java/Kotlin configuration builder) that enables **form-based authentication** — the classic username/password HTML form flow used by browser-based web apps. Calling `http.formLogin(Customizer.withDefaults())` wires up: - A **default login page** served at `GET /login` (an auto-generated HTML form) unless you override it with `.loginPage("/my-login")`. - A **`UsernamePasswordAuthenticationFilter`** that processes the form submission at `POST /login` (the *login processing URL*). ## UsernamePasswordAuthenticationFilter This filter extends `AbstractAuthenticationProcessingFilter`. When a request matches its `RequestMatcher` (by default `POST /login`), it: 1. Calls `attemptAuthentication(...)`, which reads the `username` and `password` **request parameters** (names configurable via `.usernameParameter(...)` / `.passwordParameter(...)`). 2. Builds an **unauthenticated** `UsernamePasswordAuthenticationToken(username, password)` — a `Principal`/credentials pair with `authenticated=false`. 3. Passes that token to the `AuthenticationManager` (typically a `ProviderManager` delegating to a `DaoAuthenticationProvider`, which loads the user via `UserDetailsService` and checks the password with the `PasswordEncoder`). 4. If the manager returns an **authenticated** token, `successfulAuthentication(...)` runs: it stores the token in the `SecurityContext`, persists that context through the `SecurityContextRepository` (default `HttpSessionSecurityContextRepository`, so the login survives across requests via the session), fires an `InteractiveAuthenticationSuccessEvent`, and invokes the `AuthenticationSuccessHandler`. 5. If the manager throws an `AuthenticationException`, `unsuccessfulAuthentication(...)` runs: it clears the context and invokes the `AuthenticationFailureHandler`. ## Defaults you get for free - **Login processing URL:** `POST /login`. - **Success handler:** `SavedRequestAwareAuthenticationSuccessHandler` — redirects to the URL the user originally tried to reach before being bounced to login (the *saved request*), falling back to `/`. - **Failure handler:** `SimpleUrlAuthenticationFailureHandler` — redirects to `/login?error`. - **Logout:** `/logout` is enabled separately by default. ## Stateful by nature Form login is **stateful**: the browser sends credentials **once**, and the authenticated context is stored server-side in the session. The browser then carries a `JSESSIONID` cookie; each later request is recognized without re-submitting the password. This contrasts with HTTP Basic, where the client re-sends credentials on every request. ## When to use it Use form login for **server-rendered, browser-facing web applications** where a friendly HTML login page and session-based auth are appropriate. For pure APIs or SPAs you would more often use token-based auth (JWT/OAuth2) or HTTP Basic for machine clients. ## Common gotchas - The **default `/login` page** disappears once you set a custom `.loginPage(...)` — you must then render that page yourself and permit access to it. - CSRF protection is **on by default**; the login form must include the CSRF token, or the POST is rejected. - The filter matches only its configured method+path; a mismatched form `action` silently 404s or bypasses login.

  • How does the app remember the user after a successful form login?
    The authenticated token is placed in the SecurityContext and persisted by the SecurityContextRepository — by default HttpSessionSecurityContextRepository, which stores it in the HTTP session. The browser's JSESSIONID cookie then identifies the session on later requests, so credentials are not re-sent.
  • Why might a valid username/password still fail to log in with a 403 on POST /login?
    CSRF protection is enabled by default. If the login form omits the CSRF token (_csrf), Spring rejects the POST before authentication runs. The fix is to include the token in the form (Thymeleaf/JSP tag libs add it automatically).

saying these in an interview costs you the question

  • Claiming form login is stateless / re-sends credentials each request (that's HTTP Basic).
  • Thinking the default /login page still works after setting a custom loginPage.
  • Saying UsernamePasswordAuthenticationFilter checks the password itself (the AuthenticationManager/provider does).

context

open as a page

What does Spring Security's logout() DSL configure, and what happens when a user hits /logout?

level: juniorimportance: must knowfreq 58%

basics

~10 s

The logout() DSL wires up a LogoutFilter. When a user POSTs to /logout, the filter clears the logged-in user from the SecurityContext, invalidates the HTTP session, and redirects to a success page (default /login?logout).

open as a page

What is the contract of AuthenticationManager.authenticate()? What are its three possible outcomes?

level: juniorimportance: must knowfreq 70%

basics

~10 s

AuthenticationManager has one method, authenticate(Authentication). It returns a fully authenticated Authentication if credentials are valid, throws an AuthenticationException if they are invalid, or returns null if it cannot decide.

open as a page

What is Spring Security's PasswordEncoder and why should you use it instead of storing passwords directly?

level: juniorimportance: must knowfreq 80%

basics

~20 s

PasswordEncoder is an interface that turns a raw password into a one-way, salted hash. You store the hash, never the plaintext, so a database leak doesn't expose real passwords. Its matches() method verifies a login attempt.

open as a page

What is UserDetailsService in Spring Security, and what does loadUserByUsername return?

level: juniorimportance: must knowfreq 80%

basics

~20 s

UserDetailsService is an interface with one method, loadUserByUsername(String), that looks up a user by name and returns a UserDetails object holding the username, encoded password, and authorities (roles). It throws UsernameNotFoundException if no user exists.

open as a page

What is the difference between permitAll() and anonymous() in the HttpSecurity authorization DSL?

level: middleimportance: must knowfreq 65%

basics

~20 s

permitAll() lets everyone through, logged-in or not. anonymous() allows only not-logged-in (anonymous) users; an authenticated user hitting an anonymous()-only rule is denied. Use permitAll for public pages, anonymous for login/registration pages you want to hide from signed-in users.

open as a page

What are the AbstractAuthenticationFailureEvent subtypes, and how does DefaultAuthenticationEventPublisher decide which one to fire?

level: middleimportance: must knowfreq 45%

basics

~10 s

Each kind of login failure has its own event, like AuthenticationFailureBadCredentialsEvent or AuthenticationFailureLockedEvent. DefaultAuthenticationEventPublisher maps the thrown exception type to the matching event. Unmapped exceptions fire no event unless you configure a default.

open as a page

How does httpBasic() differ from formLogin(), and what does BasicAuthenticationFilter do?

level: middleimportance: must knowfreq 75%

basics

~20 s

httpBasic() reads credentials from the 'Authorization: Basic' header on every request; formLogin() uses an HTML form and a server session. Basic is stateless and good for APIs/scripts; form login is stateful and good for browsers.

open as a page

What does SecurityContextLogoutHandler do, and which cleanup tasks are NOT its responsibility?

level: middleimportance: must knowfreq 44%

basics

~10 s

SecurityContextLogoutHandler clears the SecurityContextHolder (removing the current Authentication) and invalidates the HttpSession. It does not delete cookies or remember-me tokens — separate handlers do that.

open as a page

How does ProviderManager work? Walk through how it iterates over its AuthenticationProviders and uses the parent manager.

level: middleimportance: must knowfreq 65%

basics

~20 s

ProviderManager is the standard AuthenticationManager. It holds a list of AuthenticationProviders and asks each whether it supports the token; the first one that supports it and returns a non-null result wins. If none succeed, it delegates to an optional parent manager.

open as a page

How does DelegatingPasswordEncoder work, and what is the significance of the {id} prefix in a stored hash?

level: middleimportance: must knowfreq 75%

basics

~20 s

DelegatingPasswordEncoder stores each hash with a prefix like {bcrypt} or {argon2} that names the algorithm. On matches(), it reads the prefix, picks the matching encoder, and delegates. This lets one bean verify hashes made by different algorithms.

open as a page

How does DaoAuthenticationProvider work, and how does it collaborate with UserDetailsService and PasswordEncoder?

level: middleimportance: must knowfreq 70%

basics

~20 s

DaoAuthenticationProvider is the AuthenticationProvider for username/password login. It calls UserDetailsService to load the user, then uses a PasswordEncoder to compare the submitted password with the stored hash. If they match and the account is enabled, it returns an authenticated token.

open as a page

What is anonymous authentication in Spring Security, and what does the SecurityContext hold for an unauthenticated request?

level: juniorimportance: should knowfreq 45%

basics

~20 s

For a request with no login, Spring Security still puts a placeholder 'anonymous' user into the SecurityContext instead of leaving it empty. So code can always assume an Authentication object exists rather than handling null.

open as a page

What are Spring Security authentication events, and what publishes them?

level: juniorimportance: should knowfreq 35%

basics

~10 s

When a login succeeds or fails, Spring Security publishes an application event (like AuthenticationSuccessEvent or a failure event). You can listen to these events to log or audit logins without changing the login code.

open as a page

How does the SpEL expression isAnonymous() work, and how does it relate to isAuthenticated() and permitAll()?

level: middleimportance: should knowfreq 40%

basics

~20 s

isAnonymous() is true only when the current user is the anonymous placeholder (not logged in). isAuthenticated() is its opposite for real users. You use these in SpEL, e.g. @PreAuthorize or access() rules, to branch on login state.

open as a page

How would you build a login audit trail using @EventListener handlers for authentication events?

level: middleimportance: should knowfreq 40%

basics

~10 s

Write a Spring bean with @EventListener methods for AuthenticationSuccessEvent and AbstractAuthenticationFailureEvent. Read the username and (for failures) the exception, then persist or log an audit record. No changes to the security config are needed.

open as a page

Trace what happens inside UsernamePasswordAuthenticationFilter from form submission to a persisted authenticated session.

level: middleimportance: should knowfreq 55%

basics

~20 s

The filter reads username/password from the POST, builds an unauthenticated token, and calls the AuthenticationManager. If it returns an authenticated token, the filter saves it to the SecurityContext (and the session) and runs the success handler; otherwise it runs the failure handler.

open as a page

What is the difference between logoutSuccessUrl and LogoutSuccessHandler, and how do you make logout REST/SPA friendly?

level: middleimportance: should knowfreq 38%

basics

~10 s

logoutSuccessUrl sets the redirect target after logout. LogoutSuccessHandler is the full strategy that produces the response. For a REST/SPA client you replace the redirect with HttpStatusReturningLogoutSuccessHandler so logout returns 200 instead of a 302.

open as a page

How do you implement a custom AuthenticationProvider? What must supports() and authenticate() do?

level: middleimportance: should knowfreq 55%

basics

~20 s

Implement AuthenticationProvider with two methods. supports(Class) returns true for the token types you handle. authenticate(Authentication) validates the credentials and returns a new, fully authenticated token with authorities, throws an AuthenticationException on failure, or returns null if it can't handle the request.

open as a page

What is the BCryptPasswordEncoder work factor (strength), what does it control, and how do you choose it?

level: middleimportance: should knowfreq 65%

basics

~20 s

The work factor (strength) sets how many hashing rounds BCrypt does: 2^strength iterations. Higher strength means slower hashing and harder brute force. The default is 10; typical range is 10-12. It's stored inside the hash.

open as a page

Compare InMemoryUserDetailsManager, JdbcUserDetailsManager, and a custom UserDetailsService. When would you use each?

level: middleimportance: should knowfreq 55%

basics

~20 s

InMemoryUserDetailsManager stores users in a Map — good for demos and tests. JdbcUserDetailsManager persists users in a relational schema using a fixed default table layout. A custom UserDetailsService adapts your own user entity/store — the usual choice for real apps with domain-specific user data.

open as a page

Explain how AnonymousAuthenticationFilter works: where it sits in the chain, what it inserts, and the role of its key.

level: seniorimportance: should knowfreq 35%

basics

~20 s

Near the end of the filter chain, AnonymousAuthenticationFilter checks if the SecurityContext already has an Authentication. If not, it builds an AnonymousAuthenticationToken (default principal anonymousUser, ROLE_ANONYMOUS) using a configured key and stores it. The key lets AnonymousAuthenticationProvider verify tokens it created.

open as a page

A team reports authentication events never fire in their app. What are the likely causes and how does the wiring actually work?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Usually the AuthenticationManager has no AuthenticationEventPublisher set — common when you build ProviderManager by hand. Fix it by injecting DefaultAuthenticationEventPublisher (or Boot's autoconfigured one). Also check the failure exception is actually mapped to an event.

open as a page

What are AuthenticationSuccessHandler and AuthenticationFailureHandler, and how do you customize them for form login?

level: seniorimportance: should knowfreq 60%

basics

~20 s

They are callbacks invoked after form authentication finishes. AuthenticationSuccessHandler runs on success (default: redirect to the saved request); AuthenticationFailureHandler runs on failure (default: redirect to /login?error). You override them for custom redirects or JSON responses.

open as a page

How does CompositeLogoutHandler work, and how do you add custom logout cleanup (e.g. audit logging or token denylisting)?

level: seniorimportance: should knowfreq 30%

basics

~20 s

The logout() DSL collects all configured LogoutHandlers into a CompositeLogoutHandler, which invokes each in registration order. You add your own cleanup with addLogoutHandler(myHandler) — for example to write an audit log or add a JWT to a denylist.

open as a page

Explain the parent AuthenticationManager mechanism in ProviderManager and the credential-erasure behavior. Why do they exist?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A ProviderManager can have a parent AuthenticationManager it falls back to when none of its own providers authenticate. This lets multiple filter chains share a common global manager. After a successful authentication, ProviderManager erases the raw credentials from the returned token by default to reduce in-memory exposure.

open as a page

What does PasswordEncoder.upgradeEncoding do, and how does Spring Security use it to migrate stored passwords transparently?

level: seniorimportance: should knowfreq 55%

basics

~20 s

upgradeEncoding(storedHash) returns true when a hash was made with an older algorithm or lower strength than the current default. After a successful login, DaoAuthenticationProvider checks it and, if true, re-hashes the password with the new settings via a UserDetailsPasswordService.

open as a page

How would you implement a custom UserDetailsService that maps a JPA user entity to UserDetails, including roles/authorities, and what are the pitfalls?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Implement loadUserByUsername to fetch the entity from a repository and build a UserDetails carrying the encoded password, account flags, and authorities. Map each role to a GrantedAuthority, prefixing ROLE_ if you use hasRole. Throw UsernameNotFoundException when absent, and make sure lazy role collections are loaded.

open as a page

Beyond authentication, how do you audit authorization decisions with AuthorizationDeniedEvent, and how does that differ from authentication events?

level: principalimportance: should knowfreq 25%

basics

~10 s

Spring Security 6 can publish AuthorizationGrantedEvent and AuthorizationDeniedEvent for access-control decisions. Register a SpringAuthorizationEventPublisher bean, then use @EventListener(AuthorizationDeniedEvent.class) to audit denied access — separate from login success/failure events.

open as a page

What is an AuthenticationEntryPoint, and how does Spring choose one per mechanism when both form login and HTTP Basic are enabled?

level: principalimportance: should knowfreq 45%

basics

~20 s

An AuthenticationEntryPoint starts authentication when an unauthenticated request hits a protected resource — e.g. redirect to the login page or send a 401. With multiple mechanisms, Spring uses a DelegatingAuthenticationEntryPoint that picks one via request matchers.

open as a page

showing 1–30 of 35