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

相关推荐
小蒜学长10 小时前
“喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·宠物
xbgRS13 小时前
springboot的自动装配
java·spring boot
嘻哈∠※20 小时前
0061基于 SpringBoot 的投稿与稿件处理系统设计与实现
java·spring boot·后端
zhougl9961 天前
Java Spring Boot 爬虫技术全面介绍
java·spring boot·爬虫
用户3126874877201 天前
@Async 加了没生效?Spring Boot 异步编程全链路拆解:从线程池到自调用陷阱
java·spring boot
云烟成雨TD1 天前
Micrometer 系列【25】Spring Boot Actuator | Spring MVC、Spring WebFlux 指标
java·spring boot·micrometer
xbgRS1 天前
springBoot项目配置加载优先级
java·spring boot
云烟成雨TD1 天前
Micrometer 系列【61】统一观测:基于 Spring Boot 的生产级演示案例 | 指标集成
spring boot·云原生·链路追踪
南城以南溫暖如初1471 天前
社区健身小程序开发流程详解:技术选型与实施经验分享
java·经验分享·spring boot·mysql·vue·apache
vx-程序开发1 天前
django汽车租赁系统---附源码25360
java·javascript·spring boot·python·eclipse·django·php