API Gateway授权器上下文设置的自定义Header无法在Quarkus中通过HttpHeaders/@HeaderParam获取
你的核心思路是完全正确的——通过API Gateway映射模板把授权器上下文转成自定义Header是传递这类信息的标准做法,但有几个容易踩的细节坑导致Header没成功传到Quarkus,我帮你逐一拆解:
1. 映射模板触发条件不匹配(最可能的根因)
你当前只配置了application/json类型的映射模板,但测试用的是GET请求:GET请求通常没有请求体,也不会携带Content-Type: application/json的Header。API Gateway的规则是:只有当请求的Content-Type和你配置的映射模板类型完全匹配时,才会执行这个模板的逻辑。
换句话说,你的映射模板根本没被触发,自然也就没生成User-Email Header。
快速解决方法:
- 在API Gateway集成请求的映射模板里,添加一个
*/*类型的模板(匹配所有Content-Type),把同样的Header映射逻辑复制进去:{ "headers": { "User-Email": "$context.authorizer.email" }, "body": $input.json('$') } - 或者测试时显式给GET请求带上
Content-Type: application/jsonHeader(哪怕没有请求体),强制触发你已有的application/json模板。
2. 验证Header是否真的发出
API Gateway的执行日志显示User-Email: user@example.com,这个日志可能只是授权器上下文的日志,不是实际发给后端请求的Header日志。你需要查看集成请求的详细日志,确认这个Header确实被包含在发给Quarkus的请求里。
如果日志里确认Header已经发出,那再排查Quarkus端的问题。
3. Quarkus端的排查与验证
Quarkus默认不会拦截自定义Header,但可以通过以下方式确认问题:
(1)打印所有收到的Header
添加一个全局请求过滤器,把所有收到的Header都打印出来,确认User-Email是否真的到达Quarkus:
import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.ext.Provider; import java.util.logging.Logger; @Provider public class AllHeaderLoggingFilter implements ContainerRequestFilter { private static final Logger LOG = Logger.getLogger(AllHeaderLoggingFilter.class.getName()); @Override public void filter(ContainerRequestContext requestContext) { LOG.info("所有收到的Header:" + requestContext.getHeaders()); } }
启动Quarkus后看控制台日志,如果里面没有User-Email,说明问题还是在API Gateway这边;如果有,再检查你的代码是否有拼写错误(比如大小写,虽然HTTP Header大小写不敏感,但偶尔会有框架处理的小问题)。
(2)排查是否有自定义拦截器过滤Header
如果你项目里有自定义的ContainerRequestFilter或者Quarkus扩展(比如安全相关的),检查是否有逻辑不小心过滤掉了自定义Header。
4. 非代理集成的额外注意点
因为你禁用了Lambda Proxy集成,用的是普通HTTP集成,还要确认:
- 集成请求的「HTTP Headers」设置里,
User-Email的处理方式是Overwrite或者Pass through(不是Remove); - API Gateway和你的Quarkus服务之间的网络是通的(比如如果Quarkus在VPC里,API Gateway要配置VPC链路),不过你能收到Quarkus的响应,说明网络没问题,这个可以忽略。
临时替代方案(用于验证)
如果映射模板的问题暂时绕不开,可以先把授权器上下文放到Query参数里验证值能否传递:
修改映射模板为:
{ "queryStringParameters": { "user-email": "$context.authorizer.email" }, "body": $input.json('$') }
然后Quarkus端修改接口:
@GET @Produces(MediaType.TEXT_PLAIN) public String test( @QueryParam("user-email") String email ) { return "Query参数获取的邮箱:" + email; }
如果能拿到值,说明授权器上下文的读取是正常的,问题确实出在Header映射的触发或传递环节。
总结
你的方法本身是正确的,90%的概率是映射模板没触发导致Header没生成。先解决映射模板的Content-Type匹配问题,再用Quarkus的过滤器确认Header是否到达,应该就能解决。




