Interview Tip: Don't just say "add the dependency." Walk through JWT flow — that's what interviewers actually want to hear.
- Basic Auth — username/password in every request header (for internal/dev use)
- JWT (JSON Web Token) — token-based, stateless, used in real projects ✅
Client → POST /login (username + password)
→ Server validates credentials
→ Server generates JWT token
→ Returns token to client
Client → GET /api/users (with JWT in Authorization header)
→ Filter intercepts request
→ Validates token (signature + expiry)
→ Sets SecurityContext
→ Request reaches controller
1. Security Config
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll() // public endpoints
.anyRequest().authenticated() // all others need JWT
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}2. JWT Filter
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
String username = jwtService.extractUsername(token);
if (username != null && SecurityContextHolder.getContext()
.getAuthentication() == null) {
// validate token and set authentication
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}- Add dependency:
spring-boot-starter-security+jjwt(for JWT) SecurityFilterChain→ replaces oldWebSecurityConfigurerAdapter(deprecated)- JWT is stateless → server doesn't store session
- JWT contains: Header.Payload.Signature (Base64 encoded)
BCryptPasswordEncoder→ always use for password hashing, never plain textUserDetailsService→ implement to load user from DB
| Annotation | Use |
|---|---|
@EnableWebSecurity |
Enable Spring Security |
@PreAuthorize("hasRole('ADMIN')") |
Method-level security |
@Secured("ROLE_USER") |
Role-based access on method |