2

如何识别请求是针对 a 中的任何 Spring Boot Actuator 端点的javax.servlet.Filter

public class MyFilter implements Filter {

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
    throws IOException, ServletException {

    // Is req to any of Spring Actuator endpoint?

    chain.doFilter(req, res);
  }

我的想法是搜索调用程序类或包(org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter),但我不知道具体如何。

这是启动时应用程序日志的一部分。

EndpointHandlerMapping       : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
EndpointHandlerMapping       : Mapped "{[/env || /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/archaius || /archaius.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/health || /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)
EndpointHandlerMapping       : Mapped "{[/features || /features.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/prometheus || /prometheus.json],methods=[GET]}" onto public java.lang.Object io.micrometer.spring.autoconfigure.export.prometheus.PrometheusScrapeMvcEndpoint.invoke()
EndpointHandlerMapping       : Mapped "{[/loggers || /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/info || /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/env],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint.value(java.util.Map<java.lang.String, java.lang.String>)
EndpointHandlerMapping       : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping       : Mapped "{[/refresh || /refresh.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()
4

2 回答 2

1

您可以将执行器上下文路径更改为 /management,以便所有请求都到达http://<host>:<port>/management/<here-come-your-endpoints>

在我们使用它的 Spring Boot 1.5.3 中,可以通过指定属性轻松完成:

management.context-path=/management

application.properties文件中

这使得执行器易于跟踪,并允许灵活配置网关公开的内容和不公开的内容。

于 2018-07-01T08:25:06.877 回答
1

春季启动 2

似乎Spring Boot 2每个子版本的情况都不同。以下代码主要用于启发,必须针对特定的 Spring Boot 版本进行定制:

import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;

public class ActuatorEndpointFilter implements javax.servlet.Filter {

    @Inject
    private WebMvcEndpointHandlerMapping mvcepMapping;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        if (request instanceof HttpServletRequest) {
            HandlerExecutionChain handlerChain = mvcepMapping.getHandler((HttpServletRequest) request);
            if (handlerChain != null) {
                Object handler = handlerChain.getHandler();
                // Following condition is enought in Spring Boot 2.1.1 and 2.1.2.
                if (handler.getClass().getName().startsWith(
                        "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping")) {
                    // IT IS ACTUATOR ENDPOINT in Spring 2.1.1 and 2.1.2!!!!
                }

                // Following conditions are mandatory in Spring Boot <= 2.1.0.RELEASE
                if (handler instanceof HandlerMethod) { 
                    Object bean = ((HandlerMethod) handler).getBean();
                    if (bean.getClass().getName().startsWith(
                            "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping")) {
                        // IT IS ACTUATOR ENDPOINT in Spring 2.1.0!!!!
                    }
                }
           }
        }
        chain.doFilter(request, response);
    }
}

我怀疑第一个条件,if (handlerChain != null)即:如果WebMvcEndpointHandlerMapping返回一个处理程序,目前对于任何 Spring Boot 2 版本可能就足够了,但我没有进一步调查它。

于 2019-02-25T20:57:38.157 回答