Custom SpringBoot Interceptor for Login Authentication

This article explains how to implement a SpringBoot HandlerInterceptor to perform login authentication, configure it with a whitelist, return a unified 401 JSON response, and extend it with Redis token validation, advanced usage, and a comparison with servlet filters.

Java Tech Workshop
Java Tech Workshop
Java Tech Workshop
Custom SpringBoot Interceptor for Login Authentication

Login authentication is a core security mechanism in web projects; every request must verify login status and permissions, and unauthenticated requests are blocked.

What is a Spring Boot HandlerInterceptor?

An interceptor can execute code before a controller method, after the controller method but before view rendering, and after the entire request completes. Typical uses include:

Login status validation

Permission validation

Interface logging

Duplicate‑submission prevention

Performance monitoring

Key characteristics:

Intercepts only controller requests (static resources are not intercepted by default and can be configured)

Can abort a request and return a custom response directly

Provides a global, unified point for cross‑cutting concerns, keeping controller code clean

Core Interceptor API

Implement the HandlerInterceptor interface and override three default methods:

public interface HandlerInterceptor {
    // 1. Executed before the controller (authentication logic here)
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true; // true = allow, false = block
    }
    // 2. Executed after controller execution, before view rendering
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}
    // 3. Executed after the entire request completes (resource cleanup)
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

Login authentication only needs the preHandle method.

Custom Login Interceptor

Create LoginInterceptor.java:

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** Login interceptor: validates login status */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. Get token from request header
        String token = request.getHeader("token");
        log.info("Current request token: {}", token);
        // 2. If token is missing, block the request
        if (token == null || token.isEmpty()) {
            log.error("User not logged in, request blocked");
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"未登录,请先登录\",\"data\":null}");
            return false;
        }
        // 3. Token present – allow the request
        return true;
    }
}

Register the Interceptor and Configure a Whitelist

Create WebConfig.java that implements WebMvcConfigurer and registers the interceptor:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // intercept all requests
                .excludePathPatterns(
                        "/user/login",      // login endpoint
                        "/user/register",   // registration endpoint
                        "/swagger/**",      // API docs
                        "/v3/api-docs/**"   // OpenAPI docs
                );
    }
}

After this configuration every controller request is automatically checked for login.

Unified JSON Error Response

When authentication fails, return a Result object with HTTP status 401:

response.setContentType("application/json;charset=utf-8");
Result result = Result.fail(401, "未登录,请先登录");
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
return false;

Result JSON format:

{
  "code":401,
  "msg":"未登录,请先登录",
  "data":null
}

Full Login Validation Logic with Redis

Typical production flow:

Front‑end logs in successfully; back‑end generates a token.

Token is stored in Redis with an expiration time.

Subsequent requests carry the token in the HTTP header.

The interceptor retrieves the token, queries Redis, and decides whether to allow or block the request.

Implementation:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if (token == null || token.isBlank()) {
            return responseFail(response, "未登录,请先登录");
        }
        // Validate token in Redis
        Object user = redisTemplate.opsForValue().get("login:token:" + token);
        if (user == null) {
            return responseFail(response, "登录已过期,请重新登录");
        }
        // Token valid – allow request
        return true;
    }

    private boolean responseFail(HttpServletResponse response, String msg) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        Result result = Result.fail(401, msg);
        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
        return false;
    }
}

Advanced Interceptor Usage

Retrieve Current Request Information

HandlerMethod handlerMethod = (HandlerMethod) handler;
String methodName = handlerMethod.getMethod().getName();
String className = handlerMethod.getBean().getClass().getName();

Exclude Static Resources

registry.addInterceptor(new LoginInterceptor())
        .excludePathPatterns("/static/**", "/img/**", "/css/**", "/js/**");

Multiple Interceptor Order

registry.addInterceptor(new A()).order(1);
registry.addInterceptor(new B()).order(2);

Smaller order values execute earlier.

Interceptor vs Filter Comparison

Interceptor – Spring component; intercepts only controller requests; suited for login, permission checks, and logging.

Filter – Servlet component; intercepts all requests; suited for character encoding, CORS handling, and rate limiting.

For login authentication, an interceptor is preferred.

Summary

Implement HandlerInterceptor and override preHandle with login validation logic.

Register the interceptor in a WebMvcConfigurer implementation and configure a whitelist for login, registration, and documentation endpoints.

When the token is missing or invalid, return a 401 JSON response using a unified Result format.

Optionally integrate RedisTemplate to store tokens and enforce expiration, achieving real‑world login authentication.

Leverage advanced features such as request‑metadata extraction, static‑resource exclusion, and ordered multiple interceptors as needed.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

RedisInterceptorSpringBootHandlerInterceptorWebMvcConfigurerLogin Authentication
Java Tech Workshop
Written by

Java Tech Workshop

Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.