Reputation: 79
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
How can SpringBoot intercept a visit to actuator
Upvotes: 4
Views: 3178
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