如何在Spring Actuator/Prometheus中覆写查询参数以隐藏敏感值
解决Spring Boot 2.5.x Actuator Prometheus指标中敏感Query参数的隐藏问题
问题场景
我们有一个启用了Actuator/Prometheus的Spring Boot 2.5.x项目,部分GET请求的query参数里包含需要隐藏的敏感数据(仅针对特定query字段,并非全部参数)。默认情况下,GET请求的查询参数会被完整记录在/actuator/prometheus的指标中,示例如下:
http_client_requests_seconds_sum{client_name="client",method="GET",outcome="SUCCESS",status="200",uri="/test?query=1234&field1=value2&field2=value3",} 0.050652838
我们需要将其中query字段的具体值替换为****,最终得到:
http_client_requests_seconds_sum{client_name="client",method="GET",outcome="SUCCESS",status="200",uri="/test?query=****&field1=value2&field2=value3",} 0.050652838
尝试过的无效方案
此前尝试过以下方案,但均无法修改Actuator的Prometheus指标内容:
- 自定义Filter:仅能过滤日志,无法干预指标生成
- HttpServletWrapper、HandlerInterceptor、HandlerInterceptorAdapter:对Prometheus指标的uri标签无修改作用
- 暂时无法将请求切换为POST方式
可行解决方案:自定义MeterFilter
通过实现自定义MeterFilter,可以在指标生成阶段直接修改uri标签内容,实现敏感字段的脱敏。代码示例如下:
import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.config.MeterFilter; import org.springframework.stereotype.Component; import java.util.regex.Pattern; @Component public class SensitiveUriMeterFilter implements MeterFilter { // 正则匹配query参数,捕获参数名和对应值 private static final Pattern SENSITIVE_QUERY_PATTERN = Pattern.compile("(query=)([^&]+)"); @Override public Meter.Id map(Meter.Id id) { // 仅处理http_client_requests系列指标 if ("http_client_requests".equals(id.getName())) { String uri = id.getTag("uri"); if (uri != null && uri.contains("query=")) { // 将query字段的值替换为**** String maskedUri = SENSITIVE_QUERY_PATTERN.matcher(uri).replaceAll("$1****"); return id.withTag("uri", maskedUri); } } return id; } }
方案说明
该MeterFilter会在指标实例化前拦截http_client_requests相关指标,针对uri标签中的敏感query字段进行正则替换,既保留了其他正常参数的显示,又完成了敏感数据的脱敏,无需修改原有请求的处理逻辑。
内容的提问来源于stack exchange,提问作者Valentin Kohler
相关产品推荐
相关产品推荐

