Spring Cloud Gateway Server MVC如何从认证信息为所有请求加请求头?
在Spring Cloud Gateway Server MVC中基于认证信息统一添加请求头
问题背景
在不依赖WebFlux的Spring Cloud Gateway MVC环境下,需要从认证信息中提取字段,为所有转发至微服务的请求统一添加自定义请求头。最初尝试通过HttpServletRequestWrapper实现时,转发后的请求中缺失了添加的头信息,后续验证该方案最终可正常生效。
实现步骤
1. 自定义请求包装类
创建HttpServletRequestWrapper的子类,重写头信息相关方法,确保添加的自定义头能被后续流程正确读取:
public class CustomAuthRequestWrapper extends HttpServletRequestWrapper { private final Map<String, String> customHeaders; public CustomAuthRequestWrapper(HttpServletRequest request) { super(request); customHeaders = new HashMap<>(); } public void addCustomHeader(String name, String value) { customHeaders.put(name, value); } @Override public String getHeader(String name) { String customValue = customHeaders.get(name); return customValue != null ? customValue : super.getHeader(name); } @Override public Enumeration<String> getHeaders(String name) { List<String> headers = new ArrayList<>(Collections.list(super.getHeaders(name))); if (customHeaders.containsKey(name)) { headers.add(customHeaders.get(name)); } return Collections.enumeration(headers); } @Override public Enumeration<String> getHeaderNames() { Set<String> allHeaderNames = new HashSet<>(Collections.list(super.getHeaderNames())); allHeaderNames.addAll(customHeaders.keySet()); return Collections.enumeration(allHeaderNames); } }
2. 实现Filter处理请求
编写一个Filter,在请求转发前从认证上下文提取信息,通过自定义包装类添加请求头:
@Component @Order(Ordered.HIGHEST_PRECEDENCE) // 确保在Gateway转发Filter前执行 public class AuthHeaderInjectFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; // 从SecurityContext获取认证信息,可根据实际认证方式调整 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && !(auth instanceof AnonymousAuthenticationToken)) { // 提取需要的认证字段,示例为用户名,替换为实际业务字段 String userIdentifier = auth.getName(); CustomAuthRequestWrapper wrappedRequest = new CustomAuthRequestWrapper(request); wrappedRequest.addCustomHeader("X-Auth-User-Id", userIdentifier); filterChain.doFilter(wrappedRequest, servletResponse); return; } filterChain.doFilter(request, servletResponse); } }
3. 排查头信息缺失的关键点
如果最初出现转发后头信息丢失的情况,检查以下几点:
- Filter的执行顺序:必须确保自定义Filter在Gateway内部的转发Filter之前执行,通过
@Order设置足够高的优先级 - 认证上下文的可用性:确认在Filter执行时,认证流程已经完成,能获取到有效的认证信息
- 请求包装类的方法覆盖:确保
getHeader、getHeaders、getHeaderNames都正确重写,保证自定义头能被Gateway的转发逻辑读取
验证
配置完成后,转发到后端微服务的请求中即可看到添加的自定义请求头。若仍有问题,可通过日志打印请求头信息,验证Filter是否正确执行、头信息是否已添加到包装类中。
内容的提问来源于stack exchange,提问作者Niyaz Khannanov
相关产品推荐
相关产品推荐

