zeyang song
zeyang song

Reputation: 79

Spring Boot can't intercept actuator access

In SpringBoot version 2.1.6 unable to intercept access actuator request Now I have a global interceptor

@Component
public class ServiceFilter implements HandlerInterceptor {
//log4j
static final Logger logger = LogManager.getLogger(ServiceFilter.class);
private final RateLimiter limiter = RateLimiter.create(Runtime.getRuntime().availableProcessors() * 2 + 1);
private final ThreadLocal<ExecuteRecordDto> executeRecord = new ThreadLocal<>();

public ServiceFilter() {

}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    ExecuteRecordDto recordDto =  ExecuteRecordDto.bulider(request);
    executeRecord.set(recordDto);
    if (!limiter.tryAcquire()) {
        logger.warn("rate limiter ; json logger :  {}",CommonUtil.toJSONString(recordDto));
        response.getWriter().print(CommonUtil.toJSONString(ResultStatus.status(407, "rate limiter")));
        return false;
    }

    if (ObjectUtils.isEmpty(request.getHeader("Authorization"))) {
        logger.warn("illegal request, json logger : {} ",CommonUtil.toJSONString(recordDto));
        response.getWriter().print(CommonUtil.toJSONString(ResultStatus.status(403, "Permission denied")));
        return false;
    }
    switch (TokenHandle.checkToken(request.getHeader("Authorization"))) {
        //正常放行token
        case 0:
            response.getWriter().print(CommonUtil.toJSONString(ResultStatus.status(407, "rate limiter")));
            return true;
        //token 过期
        case 1:
            response.getWriter().println(CommonUtil.toJSONString(ResultStatus.status(408, "Token expire")));
            break;
        //非法token
        case 2:
            logger.warn("illegal token, json logger : {} ",CommonUtil.toJSONString(recordDto));
            response.getWriter().print(CommonUtil.toJSONString(ResultStatus.status(409, "Illegal token ")));
            break;
        default:
            throw new RuntimeException("server runtime exception");
    }
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    ExecuteRecordDto recordDto = executeRecord.get();
    logger.info("json logger : {}",CommonUtil.toJSONString(recordDto));
    executeRecord.remove();
}

}

And make it work

@Configuration
public class ConfigFilter implements WebMvcConfigurer {
private final ServiceFilter filter;
@Autowired
public ConfigFilter(ServiceFilter filter){
    this.filter = filter;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(filter).addPathPatterns("/**");
}
}

I requested my own api, get the effect I want 1

How can SpringBoot intercept a visit to actuator 2

Upvotes: 4

Views: 3178

Answers (1)

WiPU
WiPU

Reputation: 443

Actuator is using a different HandlerMapping (see: org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping).

This Handlermapping will be chosen over your configured RequestHandlerMapping because of the order (-100 vs 0). You can see this in the DispatcherServlet precisely the method HandlerExecutionChain getHandler(HttpServletRequest request).

In our projects we configure the access to the actuator endpoints with spring security so i'm not aware if there are any recommended ways to do it but:

The handler are chose by order so this a thing to consider, you can also try to manipulate the actuator WebMvcEndpointHandlerMapping.

Like i said i'm not sure about the right solution, but i hope it points you in the right direction to find a proper solution.

regards, WiPu

Upvotes: 3

Related Questions