JWT Authentication Filter

Building on our authentication implementation from previous lessons, we'll now create a filter to validate JWT tokens on protected endpoints.

This filter enables stateless authentication by validating tokens and establishing user context for each request.

Authentication Service Enhancement

The AuthenticationService interface needs to validate incoming tokens:

public interface AuthenticationService { // ... existing methods ... UserDetails validateToken(String token); }

Token Validation Implementation

The AuthenticationServiceImpl must decode and validate JWT tokens:

private String extractUsername(String token) { return extractAllClaims(token).getSubject(); } private Claims extractAllClaims(String token) { return Jwts.parserBuilder() .setSigningKey(getSigningKey()) .build() .parseClaimsJws(token) .getBody(); } @Override public UserDetails validateToken(String token) { String username = extractUsername(token); return userDetailsService.loadUserByUsername(username); }

JWT Filter Implementation

The JwtAuthenticationFilter processes each request to validate authentication:

@RequiredArgsConstructor @Slf4j public class JwtAuthenticationFilter extends OncePerRequestFilter { private final AuthenticationService authenticationService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { String token = extractToken(request); if (token != null) { UserDetails userDetails = authenticationService.validateToken(token); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities() ); SecurityContextHolder.getContext().setAuthentication(authentication); // Add userId to request attributes for controller access if (userDetails instanceof BlogUserDetails) { request.setAttribute("userId", ((BlogUserDetails) userDetails).getId()); } } } catch (Exception e) { // Don't throw exceptions here - just don't authenticate the request log.warn("Received invalid auth token"); } filterChain.doFilter(request, response); } private String extractToken(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if (bearerToken != null && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; } }

Enabling the Filter

Update the SecurityConfig to use our new filter:

@Bean public JwtAuthenticationFilter jwtAuthenticationFilter( AuthenticationService authenticationService) { return new JwtAuthenticationFilter(authenticationService); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception { http // ... existing configuration ... .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }

Summary

  • Created JWT authentication filter to process token-based authentication
  • Extended authentication service with token validation capabilities
  • Implemented secure token extraction and validation logic
  • Added user context to requests for controller access
  • Integrated filter into Spring Security chain for automatic processing
© 2026 Devtiro Ltd. All rights reserved