问题详情
线上跑了很久的接口突然报错403 Forbidden调不通外部接口了。
调用路径为业务项目–>公司网关–>源接口(互联网接口)。
排查经过如下历程:
- postman请求网关接口 --> 正常访问
- 检查代码是否近期有改动 --> 正常线上跑了很久的代码,没有改动
- 检查是否服务器时间不正常导致网关签名错误 --> 时间正常
- 代码本地直接请求源接口 --> 403(这里就知道是源接口做了改动)
org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.22.0</center>
</body>
</html>
]
- postman 直接请求源接口 --> 正常访问
- 比对本地代码请求参数和postman的差异
two thousand years later。。。
发现是对方限制了user-Agent的原因。httpClient发起的请求user-Agent默认是Apache-HttpClient,对方可能是了防止爬虫或恶意访问,判断了请求头的User-Agent,如果不是浏览器请求,则直接拒绝请求。
使用postman复现
怎么说呢,一般上游系统不一定配合你定位问题,变更了不通知,下游系统线上被突然来这么一下,糟老罪了。。。
解决问题
方案一 源接口变更安全控制
可以通过ip白名单等方式允许特定调用方服务发起请求
方案二 调用方设置user-agent
如果外部合作方不好沟通,那只能我们调用方设置user-agent模拟浏览器请求。
HttpHeaders headers = new HttpHeaders();
String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
headers.set("User-Agent",userAgent);
request.getHeaders().addAll(headers);
参考资料
https://www.cnblogs.com/buguge/p/11213997.html