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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
