Almost every Java backend role asks about security, and Spring Security is the framework that powers it. This guide collects 25 Spring Security interview questions with clear, code-backed answers — the kind a confident senior engineer would actually give in the room. The questions are grouped by theme (authentication, authorization and method security, filters and the SecurityFilterChain, password encoding, CSRF/CORS, and OAuth2/JWT) and roughly ordered from junior fundamentals to senior depth.
Everything here targets 2026: Spring Security 6 on Spring Framework 6 / Spring Boot 3. That means the component-based SecurityFilterChain bean, the lambda DSL, @EnableMethodSecurity, and the jakarta.* namespace — WebSecurityConfigurerAdapter is gone, and reaching for it in an interview signals you haven't touched a recent version.
Read each answer, then prove you actually know it. Don't just memorize — drill the same concepts interactively in our free practice questions and you'll retain far more than from passive reading.
How to use these questions
Work top to bottom. The early authentication and terminology questions are junior-friendly warm-ups; the filter-chain internals, method security nuances, and OAuth2/JWT sections are where senior candidates separate themselves. For each question, try to answer out loud before reading our answer — interviews are verbal, so practice verbalizing.
When a question clicks, lock it in with a quick interactive rep on /practice (free, no signup to start). If you want a structured deep-dive on the same material, our Spring Security exam guide maps these topics to the official certification weighting, and for broader Spring Boot questions, see our Spring Boot interview questions.
Authentication Interview Questions
1. What is the difference between authentication and authorization?
Authentication answers "who are you?" — it verifies identity using credentials such as a username/password, a token, or a certificate. Authorization answers "what are you allowed to do?" — it decides whether an already-identified principal may access a given resource.
Authentication always comes first. You cannot decide what a user is permitted to do until you know who they are. In Spring Security, authentication produces an Authentication object stored in the SecurityContext, and authorization (URL rules or method annotations) then reads that object to make access decisions.
In an interview: if you only get to say one thing, say "authentication is identity, authorization is permission, and authentication happens first." Interviewers ask this constantly to filter candidates who blur the two.
2. What is a principal in Spring Security?
A principal is the entity performing an action — a user, device, or system (the "who"). The data used to verify that principal is called its credentials (password, token), and the thing being accessed is the secured resource (the "what").
In Spring Security the authenticated principal is wrapped in an Authentication object. Calling authentication.getPrincipal() typically returns a UserDetails instance once login succeeds.
3. What is the UserDetails interface, and what does it hold?
UserDetails is the core interface describing a user to Spring Security. It carries the username, the (usually hashed) password, the granted authorities, and a set of account-status flags.
public interface UserDetails {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}Spring loads a UserDetails during authentication and compares the supplied credentials against it. The account-status flags (isEnabled, isAccountNonLocked, etc.) let the framework reject logins for disabled or locked accounts without any custom code.
4. What is UserDetailsService and how do you customize it?
UserDetailsService is the contract for loading user data during authentication. It defines a single method, loadUserByUsername(String username), which returns a UserDetails (or throws UsernameNotFoundException).
@Service
public class DbUserDetailsService implements UserDetailsService {
private final UserRepository repo;
public DbUserDetailsService(UserRepository repo) { this.repo = repo; }
@Override
public UserDetails loadUserByUsername(String username) {
var user = repo.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException(username));
return User.withUsername(user.getUsername())
.password(user.getPasswordHash())
.authorities(user.getRoles().toArray(String[]::new))
.build();
}
}Spring ships built-in implementations: InMemoryUserDetailsManager (dev/testing), JdbcUserDetailsManager (relational DB), and LDAP-backed variants. For anything real you usually implement the interface yourself to load users from your own data store.
5. What authentication mechanisms does Spring Security support out of the box?
Spring Security supports a wide range of mechanisms, including HTTP Basic, form login, OAuth 2.0 / OpenID Connect, SAML 2.0, and LDAP. Form login and HTTP Basic are built into the core; OAuth2, SAML, and LDAP live in dedicated starter modules.
http.formLogin(Customizer.withDefaults()) // browser login form
.httpBasic(Customizer.withDefaults()); // Authorization: Basic headerA common follow-up is "which is appropriate when?" — HTTP Basic for machine-to-machine or simple APIs, form login for traditional server-rendered apps, and OAuth2/OIDC when you want to delegate login to an external identity provider.
6. What is SecurityContextHolder and where is the Authentication stored?
SecurityContextHolder is the static holder that stores the SecurityContext for the current execution. The SecurityContext in turn holds the Authentication object representing the logged-in user.
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();By default the holder uses a ThreadLocal strategy, so the security context is bound to the current thread. That's why an authenticated principal is transparently available anywhere downstream in the same request — and also why you must propagate it explicitly when you hand work to another thread.
7. Walk through what happens during a form login.
- The user submits credentials to the login-processing URL (
/loginby default). - A
UsernamePasswordAuthenticationFilterbuilds an unauthenticatedAuthenticationtoken and hands it to theAuthenticationManager. - The manager delegates to an
AuthenticationProvider(typicallyDaoAuthenticationProvider), which calls yourUserDetailsServiceand verifies the password with the configuredPasswordEncoder. - On success, a fully-authenticated
Authenticationis stored in theSecurityContext; on failure, anAuthenticationExceptionis thrown and the user is redirected back to the login page.
Being able to name AuthenticationManager → AuthenticationProvider → UserDetailsService in order is a strong senior signal.
Authorization Interview Questions
8. What is the difference between a role and an authority?
Under the hood, Spring Security only knows about authorities — represented by GrantedAuthority objects. A role is just a convention: an authority whose name is prefixed with ROLE_.
// Authority
.requestMatchers("/reports").hasAuthority("READ_REPORTS")
// Role — "ROLE_" prefix is added automatically by hasRole
.requestMatchers("/admin/**").hasRole("ADMIN") // checks ROLE_ADMINSo hasRole("ADMIN") is effectively hasAuthority("ROLE_ADMIN"). The common gotcha: if you store an authority literally as "ADMIN" (without the prefix) and then check hasRole("ADMIN"), it will fail because the check looks for ROLE_ADMIN.
9. How do you configure URL-based authorization in Spring Security 6?
You declare a SecurityFilterChain bean and use the authorizeHttpRequests lambda DSL with requestMatchers. Order matters — rules are evaluated top to bottom, and the first match wins, so put specific patterns before broad ones.
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated());
return http.build();
}Note that requestMatchers replaced the older antMatchers / mvcMatchers, and authorizeHttpRequests replaced authorizeRequests. Always finish with anyRequest() so no path is left unsecured by accident.
10. What's the difference between antMatchers and mvcMatchers (and what replaced them)?
antMatchers matched the raw request URL using Ant-style patterns. mvcMatchers matched using Spring MVC's path-matching rules, so it also covered variants the MVC layer treats as equivalent — most importantly a trailing slash or a suffix like /orders vs /orders/. That made mvcMatchers safer, because an antMatchers("/orders") rule could be bypassed by requesting /orders/.
In Spring Security 6 both are deprecated in favor of a unified requestMatchers, which picks MVC-aware matching when Spring MVC is on the classpath. In an interview, the key point is why mvcMatchers was preferred: it closed the trailing-slash/path-suffix bypass that bit people using antMatchers.
11. How do you enable method-level security in Spring Security 6?
Add @EnableMethodSecurity to a @Configuration class. In Spring Security 6 it replaces the old @EnableGlobalMethodSecurity, and @PreAuthorize/@PostAuthorize support is enabled by default.
@Configuration
@EnableMethodSecurity // prePostEnabled = true by default
public class MethodSecurityConfig { }To turn on the JSR-250 annotations (@RolesAllowed) or the legacy @Secured annotation, set the corresponding attributes: @EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true). Knowing that @PreAuthorize is on by default — unlike the old annotation where you had to flip prePostEnabled — shows you've moved to the modern API.
12. What's the difference between @Secured, @RolesAllowed, and @PreAuthorize?
All three secure individual methods, but they differ in power. @Secured (Spring) and @RolesAllowed (JSR-250) only do simple role checks. @PreAuthorize accepts full SpEL expressions, which makes it far more expressive.
| Feature | @Secured | @RolesAllowed | @PreAuthorize |
|---|---|---|---|
| SpEL support | No | No | Yes |
| Method-argument access | No | No | Yes (#userId) |
| Boolean logic / method calls | No | No | Yes (and/or) |
@PreAuthorize("hasRole('ADMIN') or #userId == authentication.name")
public Account loadAccount(String userId) { ... }Because @PreAuthorize can reference method arguments and the current principal, it expresses ownership rules ("you may only load your own account") that the role-only annotations simply can't.
13. Which Spring Security annotations support SpEL expressions?
Four annotations accept SpEL: @PreAuthorize, @PostAuthorize, @PreFilter, and @PostFilter. @PreAuthorize runs before the method; @PostAuthorize runs after and can inspect the return value via returnObject. The filter variants prune collections in or out.
@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long id) { ... }
@PreFilter("filterObject.owner == authentication.name")
public void saveAll(List<Document> docs) { ... }By contrast, @Secured and @RolesAllowed do not support SpEL — a frequent trick question. If an interviewer asks which annotations "can't use SpEL," those two are the answer.
14. What technology makes method-level security work under the hood?
Spring AOP. When you annotate a method with @PreAuthorize (or @Secured, etc.), Spring wraps the bean in a proxy that runs a security interceptor around the call. The interceptor evaluates the expression and either proceeds or throws an AccessDeniedException.
Because it relies on proxies, the usual AOP caveats apply: security is only enforced when the call goes through the proxy. A private method, or one method calling another on the same instance (a self-invocation), bypasses the proxy and therefore the security check.
Filters & SecurityFilterChain Interview Questions
15. How is a SecurityFilterChain configured in Spring Security 6?
You declare it as a @Bean that takes an HttpSecurity, configures it with the lambda DSL, and returns http.build(). This component-based style fully replaces the removed WebSecurityConfigurerAdapter.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/css/**").permitAll()
.anyRequest().authenticated())
.formLogin(Customizer.withDefaults());
return http.build();
}
}You can define multiple SecurityFilterChain beans — for example one secured by securityMatcher("/api/**") using stateless JWT, and another for the browser UI using form login. Order them with @Order; the first chain whose matcher matches the request wins.
16. What is FilterChainProxy and how does it relate to DelegatingFilterProxy?
FilterChainProxy is the single Servlet Filter that holds and orchestrates all your SecurityFilterChain instances. For each request it picks the first chain whose URL pattern matches and runs that chain's ordered list of security filters.
The Servlet container, however, doesn't know about Spring beans, so a DelegatingFilterProxy is registered with the container and simply delegates to the Spring-managed FilterChainProxy bean.
Request → DelegatingFilterProxy → FilterChainProxy → matching SecurityFilterChain → app17. What is the default name of the Spring Security filter bean?
The filter chain that intercepts every request is registered under the bean name springSecurityFilterChain. The container-facing DelegatingFilterProxy looks up exactly this name and delegates to it.
This is a classic certification-style fill-in-the-blank. The name to remember is springSecurityFilterChain (the FilterChainProxy instance), which sits in front of all your individual SecurityFilterChain beans.
18. At what levels can Spring Security enforce access control?
Spring Security enforces access control at two main levels:
- Web/URL level — via the servlet filter chain and
authorizeHttpRequestsrules, applied to incoming HTTP requests. - Method level — via AOP and annotations such as
@PreAuthorize/@Securedon service methods.
Securing the service layer with method security matters because it protects business logic regardless of how it's reached — through MVC, a scheduled job, or a message listener — whereas URL rules only guard the HTTP entry point. Defense in depth means applying both.
19. What does the order of authorization rules mean, and why does it matter?
Authorization rules are evaluated in declaration order, and the first match wins. A broad rule placed before a specific one will shadow it.
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN") // specific first ✅
.requestMatchers("/**").authenticated()); // broad lastIf you reversed those two lines, /** would match /admin/** first and the admin-only restriction would never apply. The safe habit: most-specific patterns at the top, the catch-all anyRequest() at the bottom.
Password Encoding Interview Questions
20. Why must you never store passwords in plain text, and what does Spring Security provide?
Storing plain-text (or reversibly-encrypted) passwords means a database breach instantly leaks every user's credentials. Spring Security mandates a one-way, salted PasswordEncoder so the stored value can't be reversed back to the original password.
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}BCryptPasswordEncoder is the common default: it's adaptive (you can raise the work factor as hardware improves) and generates a random salt per password automatically, so two identical passwords hash differently. At login, the encoder's matches(raw, encoded) re-hashes the input and compares — it never decrypts.
21. What is DelegatingPasswordEncoder and why is it the recommended default?
DelegatingPasswordEncoder reads an {id} prefix on each stored hash — for example {bcrypt}$2a$... or {argon2}$argon2id$... — and routes verification to the matching encoder. It's what PasswordEncoderFactories.createDelegatingPasswordEncoder() returns and is the recommended default.
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
// encodes new passwords with bcrypt, but can still verify {noop}, {pbkdf2}, {argon2}, ...The big win is migration: you can upgrade your hashing algorithm over time without invalidating existing passwords, because the {id} prefix tells the encoder how each historical hash was produced. A bare BCryptPasswordEncoder can't verify a value stored with a different scheme; the delegating encoder can.
CSRF & CORS Interview Questions
22. What is CSRF, and how does Spring Security protect against it?
CSRF (Cross-Site Request Forgery) tricks an authenticated user's browser into sending an unwanted state-changing request to a site it's already logged into, abusing the trust that site places in the browser's cookies. Spring Security enables CSRF protection by default.
The defense is a per-session synchronizer token: the server embeds an unguessable token in forms, then requires that token on every state-changing request (POST, PUT, DELETE, PATCH). Requests without a valid token are rejected. Safe, read-only methods (GET, HEAD, OPTIONS) are not checked, because they shouldn't change state.
23. When is it acceptable to disable CSRF protection?
CSRF protection guards cookie/session-based browser flows. It's reasonable to disable it for a stateless REST API that authenticates every request with a bearer token (e.g. JWT) in the Authorization header rather than a session cookie — there's no ambient cookie for an attacker to ride, so the token-per-request model already prevents forgery.
http.csrf(csrf -> csrf.disable()) // only for stateless, token-authenticated APIs
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));In an interview: never say "just disable CSRF to fix the 403." Explain that it's safe only because the API is stateless and token-authenticated; for any cookie-session app, leave it on.
24. How does CORS differ from CSRF, and how do you configure it?
They're often confused but solve opposite problems. CSRF is a defense against forged cross-site requests. CORS (Cross-Origin Resource Sharing) is a relaxation — it tells the browser which other origins are allowed to call your API, loosening the same-origin policy.
In Spring Security you wire CORS into the filter chain and back it with a CorsConfigurationSource:
http.cors(Customizer.withDefaults()); // picks up a CorsConfigurationSource beanThe key insight for an interview: CORS is enforced by the browser, not the server — it's not an authentication mechanism. You enable CORS to let a trusted front-end on a different origin talk to your API; you keep CSRF protection to stop untrusted origins from forging cookie-based requests.
OAuth2 & JWT Interview Questions
25. What's the difference between an OAuth2 client and a resource server, and where does JWT fit?
Spring Security splits OAuth2 into two roles. An OAuth2 client delegates login to an external authorization server (Google, GitHub, Keycloak) — your app receives the user's identity and tokens without ever handling their password. A resource server is an API that protects its endpoints by validating an incoming bearer token on each request.
JWT is the token format usually exchanged. A resource server validates a JWT's signature and claims (it's self-contained, so no round-trip to the auth server is needed) and builds an Authentication from its claims:
http.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));In short: the client module is about logging your users in via a third party; the resource server module is about protecting your API with the tokens those flows issue. Mixing up the two is one of the most common stumbles in security interviews.
Frequently Asked Questions
What Spring Security topics come up in interviews?
The recurring core is: the authentication vs authorization distinction, the SecurityFilterChain / FilterChainProxy model, how UserDetailsService and PasswordEncoder drive login, URL vs method-level authorization (@PreAuthorize and friends), CSRF/CORS, and — for senior or platform roles — OAuth2/OIDC and JWT resource servers. Expect the Spring Security 6 migration to come up too: interviewers like to confirm you know WebSecurityConfigurerAdapter is gone and that configuration is now a SecurityFilterChain bean. Security questions sit alongside the broader Spring framework interview questions on IoC, beans and AOP, so prepare both. Drilling these interactively on /practice builds the recall speed passive reading can't.
Are these real interview questions?
These are questions written in the style of real Spring Security interviews and the Spring Professional exam, with original, detailed explanations — not leaked questions, dumps, or any "guaranteed pass" material. They reflect the topics interviewers and the certification consistently test, so practicing them prepares you for the substance you'll actually face.
How has SecurityFilterChain changed configuration in Spring Security 6?
In Spring Security 6 you no longer extend WebSecurityConfigurerAdapter (it was removed). Instead you declare a SecurityFilterChain bean that takes an HttpSecurity, configure it with the lambda DSL (authorizeHttpRequests, requestMatchers, formLogin, etc.), and return http.build(). You can register multiple such beans — ordered with @Order and scoped with securityMatcher — to apply different rules to different parts of your app, such as a stateless JWT chain for /api/** and a form-login chain for the UI.
You now have 25 solid Spring Security interview questions spanning authentication, authorization and method security, the filter chain, password encoding, CSRF/CORS, and OAuth2/JWT — junior fundamentals through senior depth. The fastest way to turn "I read it" into "I can answer it under pressure" is active recall: head to our free interactive practice questions and drill these until they're automatic, and if certification is your goal, work through the Spring Security exam guide and the full exam guide next.