← Home
☕Java Developer Interview Questions — Fresher to 5 YOEJava Dev InterviewNEW
🔐

Spring Security

AuthN/AuthZ, JWT, filter chain, CORS/CSRF · 8 questions

1

What is the difference between authentication and authorization?

Must Know🌱 Fresher

Authentication answers "who are you?" — verifying an identity, typically via credentials (username/password, a JWT, an OAuth token). Authorization answers "what are you allowed to do?" — once identity is established, deciding whether this specific user can access a given resource or perform a given action (based on roles/ authorities/permissions). Authentication always happens first; authorization decisions are meaningless without a verified identity to check permissions against.

Spring Security
2

What is the Spring Security filter chain?

Must Know📊 Mid

Spring Security intercepts every incoming request through a chain of servlet filters, each responsible for one concern, before the request ever reaches your controller.

🔗 A typical (simplified) filter chain
Request
   |
   v
CorsFilter                       -- handles CORS preflight/headers
   |
   v
CsrfFilter                       -- validates CSRF token (if enabled)
   |
   v
UsernamePasswordAuthenticationFilter / your JWT filter
   |                                -- authenticates the request, populates SecurityContext
   v
ExceptionTranslationFilter       -- catches AccessDeniedException/AuthenticationException
   |
   v
FilterSecurityInterceptor        -- final authorization check against configured rules
   |
   v
Your DispatcherServlet / Controller

If any filter rejects the request (e.g. no valid token), it short-circuits — the request never reaches your controller at all.

Spring SecurityFilter Chain
3

How do you implement JWT-based stateless authentication with Spring Security?

Must Know📊 Mid

The typical flow: a login endpoint validates credentials and returns a signed JWT; the client sends that token in the Authorization: Bearer <token> header on every subsequent request; a custom filter (extending OncePerRequestFilter, so it runs exactly once per request) intercepts each request, validates the token's signature and expiry, and — if valid — manually populates the SecurityContext with an authenticated principal, before letting the request continue down the chain.

JWT validation filter (sketch)java
class JwtAuthFilter extends OncePerRequestFilter {
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
        String token = extractBearerToken(req);
        if (token != null && jwtUtil.isValid(token)) {
            Authentication auth = jwtUtil.buildAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        chain.doFilter(req, res); // continue regardless -- downstream authorization still enforces access
    }
}

Because the server never stores session state, this is fully stateless — any instance in a scaled-out cluster can validate any request's token independently. See JWT vs Session/OAuth → for the deeper trade-off discussion (revocation, token size, refresh tokens).

Spring SecurityJWT
4

Why must passwords be hashed with a PasswordEncoder (e.g. BCrypt) instead of stored or compared in plaintext?

Must Know🌱 Fresher

Storing plaintext passwords means a single database breach exposes every user's actual password — devastating given how often people reuse passwords across services. PasswordEncoder implementations like BCrypt apply a one-way, salted hash: the same password hashes to a different output every time (a random salt is embedded in the result), and the hash can't be reversed back to the original password. Login compares by re-hashing the submitted password with the stored salt and checking for a match — the plaintext password itself is never stored or needed again after signup.

Encoding and matchingjava
PasswordEncoder encoder = new BCryptPasswordEncoder();
String hash = encoder.encode("myPassword123");     // different output every call
encoder.matches("myPassword123", hash);             // true -- verifies without ever decrypting

BCrypt is also deliberately slow (configurable work factor) — a defense against brute-force/rainbow-table attacks, unlike a fast general-purpose hash like plain SHA-256.

Spring SecurityPassword Hashing
5

What is method-level security (@PreAuthorize, @Secured)?

Important📊 Mid

Method-level security lets you enforce authorization rules directly on a service/controller method (rather than only at the URL level in the security config), checked before the method body runs — implemented as an AOP proxy, same mechanism as @Transactional.

@PreAuthorize with a SpEL expressionjava
@PreAuthorize("hasRole('ADMIN')")
void deleteUser(Long id) { ... }

@PreAuthorize("#userId == authentication.principal.id or hasRole('ADMIN')")
User getProfile(Long userId) { ... } // users can view their own profile, admins can view any

@Secured is an older, simpler alternative — only supports role checks, no SpEL expressions, so @PreAuthorize is generally preferred today for its flexibility.

Spring SecurityAuthorization
6

What is CSRF, and why is it usually disabled for stateless REST APIs?

Important📊 Mid

CSRF (Cross-Site Request Forgery) tricks a logged-in user's browser into submitting an unwanted state-changing request to a site it's authenticated with, relying on the browser automatically attaching cookies to that request. Spring Security's CSRF protection requires a unique, unpredictable token on every state-changing request, which an attacker's page can't know.

This attack specifically depends on cookie-based session authentication. A stateless REST API secured with a JWT sent in an explicit Authorization header (not a cookie) isn't vulnerable the same way — the browser won't automatically attach that header to a forged cross-site request — so CSRF protection is commonly disabled for such APIs (while staying essential for any endpoint that still relies on cookie-based sessions).

Spring SecurityCSRF
7

What is SecurityContextHolder, and how does Spring Security know who the current user is on each request?

Advanced📊 Mid

SecurityContextHolder is a static holder that stores the current request's SecurityContext (which wraps the Authentication object — the principal, their granted authorities, and credentials) — by default, in a ThreadLocal, so it's naturally scoped to the thread handling the current request and never leaks between concurrent requests. An authentication filter populates it early in the filter chain; anywhere later in the request — controllers, services, @PreAuthorize expressions — can call SecurityContextHolder.getContext().getAuthentication() to find out who's making the request, without threading a "current user" parameter through every method call.

Spring Security
8

What is the difference between hasRole() and hasAuthority()?

Optional📊 Mid

Functionally, both check whether the authenticated user has a given granted authority — the only difference is a naming convention: hasRole('ADMIN') is sugar for hasAuthority('ROLE_ADMIN') — it automatically prepends the ROLE_ prefix Spring Security's role-based checks conventionally expect. hasAuthority(...) checks the exact string with no prefix magic, which matters if your authorities aren't role-shaped (e.g. fine-grained permissions like "orders:write" rather than broad roles).

Spring SecurityAuthorization