【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)

相关推荐
尘觉4 小时前
中秋节与 Spring Boot 的思考:一场开箱即用的团圆盛宴
java·spring boot·后端
AAA修煤气灶刘哥6 小时前
监控摄像头?不,我们管这个叫优雅的埋点艺术!
java·后端·spring cloud
半旧夜夏7 小时前
【设计模式】核心设计模式实战
java·spring boot·设计模式
皮皮林5517 小时前
SpringBoot 控制台秒变炫彩特效,秀翻同事指南!
spring boot
IT学长编程8 小时前
计算机毕设选题 基于SpringBoot的书店管理系统的设计与实现 网上书店系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·前后端分离·网上书店系统·书店管理系统
IT学长编程8 小时前
计算机毕设选题 基于SpringBoot的房产租赁管理系统 房屋租赁系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·房屋租赁系统·房产租赁系统·文档报告
李慕婉学姐9 小时前
【开题答辩过程】以《基于 Spring Boot 的宠物应急救援系统设计与实现》为例,不会开题答辩的可以进来看看
数据库·spring boot·宠物
yunmi_10 小时前
Spring Cloud Netfilx -- Ribbon:负载均衡工具(代码示例)
spring cloud·ribbon·maven·负载均衡
一只大头猿10 小时前
基于SpringBoot和Vue的超市管理系统
前端·vue.js·spring boot