【Spring Actuator】通过拦截器进行拦截并添加Basic身份验证(不使用Spring Security)

背景

最近被市安全办公室通知,A服务的/actuator/*接口存在安全隐患

问题现象

可公网且未身份验证的访问/actuator/*接口,env中包含非常多的系统信息,包括数据库连接,properties等。

解决思路

注意:网上很多文章都是通过添加 spring security进行拦截,但是我们的项目是微服务节点,并没有使用它。 理由如下:

  1. 框架太重,如果仅做一个basic验证简直杀鸡用牛刀;
  2. 存在隐患。因为微服务本身不需要,贸然引用很有可能出现其他异常。

所以,我们选择自己实现功能。思路如下:

  1. 添加Web拦截器
  2. Web拦截器中去判断url和检查Authorization请求头
  3. 根据配置文件,判断Authorization的内容是否有效,无效则返回错误信息

解决方案(代码)

  1. 编写拦截器

代码描述:编写一个拦截器,用于处理basic身份验证信息是否有效。

java 复制代码
public class ActuatorEndpointInterceptor implements Ordered, HandlerInterceptor {

    private final static String BASIC_USERNAME_PASSWORD = "username:password";

    protected String basicAuth() {
        return BASIC_USERNAME_PASSWORD;
    }


    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authValue = request.getHeader(GatewayParseRequestHeadersConstant.AUTHORIZATION);
        if (StringUtils.isNotBlank(authValue)) {
            String basic = authValue.replace("Basic", "");
            String encode = Base64Util.decode2String(basic.trim());
            return encode.equals(this.basicAuth());
        }
        response.getOutputStream().write("Illegal Request,Authorization error".getBytes(StandardCharsets.UTF_8));
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return false;
    }

}
  1. 配置Spring Actuator Configuration
java 复制代码
@RequiredArgsConstructor
@Configuration
@ConditionalOnClass(InvalidEndpointRequestException.class)
public  class WebActuatorMvcEndpointConfiguration extends WebMvcEndpointManagementContextConfiguration {

    /**
     * spring ActuatorEndpointInterceptor 身份拦截器
     */
    @Bean
    @ConditionalOnMissingBean
    public ActuatorEndpointInterceptor actuatorEndpointInterceptor() {
        return new ActuatorEndpointInterceptor();
    }

    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
                                                                         ServletEndpointsSupplier servletEndpointsSupplier,
                                                                         ControllerEndpointsSupplier controllerEndpointsSupplier,
                                                                         EndpointMediaTypes endpointMediaTypes,
                                                                         CorsEndpointProperties corsProperties,
                                                                         WebEndpointProperties webEndpointProperties,
                                                                         Environment environment,
                                                                         ObjectProvider<ActuatorEndpointInterceptor[]> interceptors
    ) {
        WebMvcEndpointHandlerMapping webMvcEndpointHandlerMapping = super.webEndpointServletHandlerMapping(webEndpointsSupplier, servletEndpointsSupplier, controllerEndpointsSupplier, endpointMediaTypes, corsProperties, webEndpointProperties, environment);
        ActuatorEndpointInterceptor[] ifAvailable = interceptors.getIfAvailable();
        if (ifAvailable != null) {
            webMvcEndpointHandlerMapping.setInterceptors(Arrays.stream(ifAvailable).toArray());
        }
        return webMvcEndpointHandlerMapping;
    }
}

代码描述:SpringActuator 使用的WebMvcEndpointHandlerMappingRequestMappingInfoHandlerMapping的之类,专门为SpringActuator配置。它默认的Bean是没有任何拦截器相关的配置,如下图:

但是实际WebMvcEndpointHandlerMapping有一个setInterceptors的方法。 所以上述第二段代码,就是改了这部分逻辑。

冷知识

  1. WebMvcEndpointHandlerMapping的拦截器不用配置includePath和excludePath。
  2. basic身份验证,实际上可以通过返回特定的数据直接让浏览器弹出一个框输入账号密码。像这样

Spring Web拦截器让浏览器自动弹出账号密码框 - 掘金 (juejin.cn)

相关推荐
惜茶11 小时前
vue+SpringBoot(前后端交互)
java·vue.js·spring boot
杰克尼11 小时前
springCloud_day07(MQ高级)
java·spring·spring cloud
NHuan^_^13 小时前
SpringBoot3 整合 SpringAI 实现ai助手(记忆)
java·人工智能·spring boot
han_hanker13 小时前
springboot 一个请求的顺序解释
java·spring boot·后端
杰克尼13 小时前
SpringCloud_day05
后端·spring·spring cloud
MaCa .BaKa13 小时前
44-校园二手交易系统(小程序)
java·spring boot·mysql·小程序·maven·intellij-idea·mybatis
希望永不加班14 小时前
SpringBoot 静态资源访问(图片/JS/CSS)配置详解
java·javascript·css·spring boot·后端
oh LAN14 小时前
RuoYi-Vue-master:Spring Boot 4.x (JDK 17+) (环境搭建)
java·vue.js·spring boot
秋风不问归客15 小时前
Springboot面试全面整理
spring boot·后端·面试
鬼先生_sir15 小时前
SpringCloud-GateWay网关
java·spring cloud·gateway