DotNet YARP 中 ReverseProxy 如何去重请求头里的 Authorization
在使用 YARP 做反向代理时,有时会遇到下游服务收到多个 Authorization 请求头的问题。
典型场景是:
- 客户端本身已经带了
Authorization - 代理层又通过 Transform 额外追加了一次
Authorization - 最终下游收到重复的认证头,导致鉴权异常
这篇文章重点说明两个问题:
- 为什么会出现重复的
Authorization - 在
YARP ReverseProxy里应该如何正确处理
为什么会出现重复的 Authorization
YARP 默认会把大多数入站请求头复制到代理请求中。
也就是说,如果客户端请求本身带了:
http
Authorization: Bearer user-token
那么这个头默认会被转发到下游。
如果你又在 YARP 配置里额外加了一条类似"设置 Authorization"的规则,就可能形成重复:
- 原始请求头复制了一份
- Transform 又新增了一份
结果就是下游看到多个 Authorization。
核心思路:不要追加,而是先删后设
如果目标是让下游只收到一个 Authorization,最稳妥的方式是:
- 先移除原始
Authorization - 再显式设置你要传给下游的
Authorization
也就是:
RemoveSet
而不是直接 Append。
YARP 配置方式
方案 1:先删除 Authorization,再重新设置
这是最常见、最推荐的做法。
json
{
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "/api/{**catch-all}"
},
"Transforms": [
{ "RequestHeaderRemove": "Authorization" },
{ "RequestHeader": "Authorization", "Set": "Bearer xxx" }
]
}
},
"Clusters": {
"cluster1": {
"Destinations": {
"destination1": {
"Address": "https://backend.example.com/"
}
}
}
}
}
}
适用于下面这种情况:
- 客户端带来的 token 不想直接透传
- 希望代理层统一改写为内部 token
- 需要确保下游只收到一个
Authorization
方案 2:如果只是不要转发 Authorization
如果需求不是"替换",而只是"不要把客户端的 Authorization 往下游传",那只删掉即可:
json
{
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "/api/{**catch-all}"
},
"Transforms": [
{ "RequestHeaderRemove": "Authorization" }
]
}
}
}
}
这个配置的含义很直接:
- 客户端可以带
Authorization - 但 YARP 转发给下游时会把它移除
方案 3:只转发白名单请求头
还有一种更彻底的方式:不要默认复制所有请求头,而是只允许特定请求头通过。
例如:
json
{
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "/api/{**catch-all}"
},
"Transforms": [
{ "RequestHeadersAllowed": "Content-Type;Accept;X-Request-Id" }
]
}
}
}
}
这个配置表示只允许以下请求头被转发:
Content-TypeAcceptX-Request-Id
因为 Authorization 不在白名单里,所以不会被转发。
适用于这些场景:
- 安全要求较高
- 不希望客户端头信息污染内部服务
- 希望代理层完全控制下游收到的头
最容易踩的坑
1. 误用 Append 导致重复
如果使用的是"追加 header"的方式,而不是"覆盖 header"的方式,就容易出现重复。
错误思路:
- 先保留客户端的
Authorization - 再追加一个新的
Authorization
这样下游很可能拿到两个值。
正确思路:
- 先删
- 再设
2. 以为 YARP 会自动帮你去重
YARP 的重点是"转发"和"变换",不是自动帮你做业务语义上的去重。
对于 Authorization 这类敏感头,建议显式控制,不要依赖隐式行为。
3. 忘了默认会复制请求头
很多问题的根源其实不是 Transform 本身,而是忽略了这一点:
YARP 默认会复制大多数入站请求头。
所以只要客户端已经带了 Authorization,你后面任何"再设置一次"的操作,都要先思考是否会形成重复。
怎么选方案
情况 1:我要替换 Authorization
json
"Transforms": [
{ "RequestHeaderRemove": "Authorization" },
{ "RequestHeader": "Authorization", "Set": "Bearer xxx" }
]
情况 2:我要禁止 Authorization 透传
json
"Transforms": [
{ "RequestHeaderRemove": "Authorization" }
]
情况 3:我要严格限制所有可转发请求头
json
"Transforms": [
{ "RequestHeadersAllowed": "Content-Type;Accept;X-Request-Id" }
]
结论
在 DotNet YARP 中,Authorization 请求头重复的根本原因通常是:
- 默认请求头复制
- 叠加了额外的请求头设置或追加
正确处理方式不是依赖"自动去重",而是显式控制:
- 要替换:
RequestHeaderRemove+Set - 要屏蔽:
RequestHeaderRemove - 要白名单:
RequestHeadersAllowed
一句话总结就是:
在 YARP 里处理
Authorization,最稳妥的做法是先删后设,不要直接追加。