Backend Development 12 min read

Four Ways to Implement a Generic AppKey Whitelist in Spring Boot

This article explains four approaches to adding a generic appkey whitelist check in a Spring Boot web framework—traditional AOP, HandlerInterceptor, custom HandlerMethodArgumentResolver, and Servlet Filter—providing implementation steps, code examples, and a discussion of their execution order and extensibility.

Architecture Digest
Architecture Digest
Architecture Digest
Four Ways to Implement a Generic AppKey Whitelist in Spring Boot

The article introduces four ways to implement a generic authentication (appkey) whitelist in a Spring Boot web framework, including traditional AOP, Interceptor, ArgumentResolver, and Filter, and provides corresponding example code along with a brief summary of their execution order.

Preface

Recently overwhelmed by endless business requirements, the author finally received a task that pushed them out of their comfort zone: adding a generic appkey whitelist validation feature to the internal web framework, aiming for better extensibility.

The framework, built on Spring Boot, sits between business code and the Spring framework, providing common utilities such as logging, feature toggles, and generic parameter parsing. The author decided to document the solution as a technical overview.

Traditional AOP

For this requirement, the first thought is to use Spring‑Boot's AOP support: declare a pointcut before controller methods and handle the whitelist check there.

Implementation

Steps:

Declare an aspect class with @Aspect , e.g., WhitelistAspect .

Add a pointcut method whitelistPointcut() that matches only methods annotated with a custom @Whitelist annotation.

Use @Before to define a advice method checkWhitelist() that runs before the controller method and performs the whitelist validation.

Aspect class pseudo‑code:

@Aspect
public class WhitelistAspect {
    @Before(value = "whitelistPointcut() && @annotation(whitelist)")
    public void checkAppkeyWhitelist(JoinPoint joinPoint, Whitelist whitelist) {
        checkWhitelist();
        // can use joinPoint.getArgs() to get controller method arguments
        // can use whitelist variable to get annotation parameters
    }

    @Pointcut("@annotation(com.zhenbianshu.Whitelist)")
    public void whitelistPointCut() {}
}

Apply the @Whitelist annotation on controller methods to enable the check.

Extension

The example uses an annotation to declare the pointcut, and the annotation can be extended with additional attributes (e.g., uid() ) to support other whitelist criteria. Spring AOP also supports other pointcut expressions ( execution , bean ) and advice types ( @Around , @After ).

Interceptor

Spring's HandlerInterceptor is another suitable way. An interceptor runs before a controller action and can decide whether to allow the request.

Implementation

Steps:

Define an interceptor class WhitelistInterceptor that implements HandlerInterceptor .

Implement the preHandle() method to retrieve the @Whitelist annotation and perform the check; return false to block the request.

Optionally implement postHandle() and afterCompletion() for post‑processing.

Register the interceptor in a custom WebMvcConfigurerAdapter implementation.

Interceptor class:

@Component
public class WhitelistInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Whitelist whitelist = ((HandlerMethod) handler).getMethodAnnotation(Whitelist.class);
        // whitelist.values(); // use request to get parameters, whitelist to get annotation values
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

Extension

Enable the interceptor by adding it in a configuration class that extends WebMvcConfigurerAdapter :

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WhitelistInterceptor()).addPathPatterns("/*").order(1);
    }
}

Note that the interceptor returns HTTP 200 with an empty body when it allows the request.

ArgumentResolver

Spring's HandlerMethodArgumentResolver allows custom method‑parameter binding before the controller is invoked.

Implementation

Create a custom parameter type AuthParam containing appkey fields.

Implement AuthParamResolver that implements HandlerMethodArgumentResolver .

In supportsParameter() , return true when the method parameter type is AuthParam .

In resolveArgument() , obtain the request and the @Whitelist annotation, perform the whitelist check, and return an AuthParam instance.

Add AuthParam as a method argument in controller actions to activate the resolver.

Resolver class:

@Component
public class AuthParamResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(AuthParam.class);
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Whitelist whitelist = parameter.getMethodAnnotation(Whitelist.class);
        // validate whitelist using webRequest and whitelist
        return new AuthParam();
    }
}

Extension

Register the resolver in the same WebMvcConfigurerAdapter implementation:

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List
argumentResolvers) {
        argumentResolvers.add(new AuthParamResolver());
    }
}

Filter

A javax.servlet.Filter is defined by the Servlet specification and runs before Spring's dispatch. It cannot directly access Spring beans, so it works with raw ServletRequest and ServletResponse .

Implementation

Filter class:

public class WhitelistFilter implements javax.servlet.Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // decide whether to block the request
        chain.doFilter(request, response); // must invoke to continue processing
    }
    @Override
    public void destroy() {}
}

Extension

Register the filter via a FilterRegistrationBean :

@Configuration
public class FilterConfiguration {
    @Bean
    public FilterRegistrationBean someFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new WhitelistFilter());
        registration.addUrlPatterns("/*");
        registration.setName("whitelistFilter");
        registration.setOrder(1); // execution order
        return registration;
    }
}

Summary

All four implementations are valid in different scenarios. Their invocation order is: Filter (Servlet level) → Interceptor → ArgumentResolver → AOP pointcut. Logging from a combined project confirms this sequence.

javaaopSpring BootauthenticationInterceptorfilterArgumentResolver
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login 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.