Spring Cloud Gateway请求头过滤器失效:无法移除Authorization头
问题分析
Spring Cloud Gateway 默认将Authorization标记为敏感请求头,这类头被设计为只读状态,直接使用官方提供的RemoveRequestHeader过滤器会触发UnexpectedOperationException,这是框架的默认机制导致的,并非你的操作有误。
解决方案
方案1:调整敏感头配置,使用官方过滤器(推荐长期方案)
通过修改配置将Authorization从默认敏感头列表中移除,之后就可以正常使用官方的RemoveRequestHeader过滤器完成操作。
修改你的application.yml配置如下:
spring: cloud: gateway: # 剔除默认敏感头中的Authorization,保留其余默认敏感头 sensitive-headers: Cookie,Set-Cookie routes: - id: test-route uri: http://52.20.148.183 predicates: - Path=/test/** filters: - StripPrefix=1 - RemoveRequestHeader=Authorization - RemoveRequestHeader=Postman-Token
说明:框架默认敏感头包含
Authorization、Cookie、Set-Cookie,此处仅保留后两者,将Authorization移出敏感头范围后,官方过滤器即可正常修改该头信息。
方案2:优化自定义GlobalFilter(替代方案)
若不想修改全局敏感头配置,可以简化你当前的自定义过滤器逻辑,绕过原始头的只读限制:
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class RemoveAuthHeaderFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 创建新的可变HttpHeaders实例,复制原始头并移除目标字段 HttpHeaders newHeaders = new HttpHeaders(); newHeaders.putAll(exchange.getRequest().getHeaders()); newHeaders.remove(HttpHeaders.AUTHORIZATION); newHeaders.remove("Postman-Token"); // 构建替换后的请求并继续执行链路 var modifiedRequest = exchange.getRequest().mutate() .headers(headers -> headers.clear().addAll(newHeaders)) .build(); return chain.filter(exchange.mutate().request(modifiedRequest).build()); } }
为什么直接使用
exchange.mutate()会失败? 原始请求的HttpHeaders是不可变对象(ImmutableHttpHeaders),直接调用headers(headers -> headers.remove(...))会因尝试修改不可变集合抛出异常,必须创建新的可变HttpHeaders实例来替换原始头信息。
内容的提问来源于stack exchange,提问作者TechnicalFreak
相关产品推荐
相关产品推荐

