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

相关推荐
v***885634 分钟前
Springboot项目:使用MockMvc测试get和post接口(含单个和多个请求参数场景)
java·spring boot·后端
javaの历练之路1 小时前
基于 SpringBoot+Vue2 的前后端分离博客管理系统(含 WebSocket+ECharts)
spring boot·websocket·echarts
6***09262 小时前
如何快速搭建简单SpringBoot项目网页
java·spring boot·intellij-idea
z***56562 小时前
springboot整合mybatis-plus(保姆教学) 及搭建项目
spring boot·后端·mybatis
q***98522 小时前
Spring Boot:Java开发的神奇加速器(二)
java·spring boot·后端
小蒜学长3 小时前
基于spring boot的汽车4s店管理系统(代码+数据库+LW)
java·数据库·spring boot·后端·汽车
一 乐3 小时前
餐厅管理智能点餐系统|基于java+ Springboot的餐厅管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端
y***13644 小时前
【wiki知识库】07.用户管理后端SpringBoot部分
spring boot·后端·状态模式
小坏讲微服务4 小时前
Spring Cloud Alibaba 整合 Scala 教程完整使用
java·开发语言·分布式·spring cloud·sentinel·scala·后端开发
过客随尘4 小时前
Spring AOP以及事务详解(一)
spring boot·后端