如何让AWS API Gateway代理传递请求中的证书至第三方API?
解决AWS API Gateway作为代理时第三方API证书验证失败的问题
1. 先明确证书传递的核心问题
直接请求第三方API带证书能成功,但走API Gateway代理就失败,大概率是证书没有被正确传递到第三方API,或者API Gateway的代理逻辑拦截/修改了证书相关的请求内容。先区分第三方API要求的证书类型:
- 如果是双向TLS(mTLS)认证:API Gateway默认不会转发客户端的TLS证书到后端,这种场景不能直接用HTTP代理集成。
- 如果是证书内容放在请求头/请求体:要检查API Gateway是否允许转发对应的自定义头,或者映射模板是否过滤了相关内容。
2. 针对mTLS场景的解决方案
这种情况必须通过Lambda中转请求,让Lambda作为客户端携带证书访问第三方API:
- 把客户端证书(PEM格式的证书和私钥)上传到S3,给Lambda角色配置S3读取权限。
- 创建Lambda函数,在函数中加载证书,用HTTP客户端(比如Python的
requests)发起请求时指定证书参数。 - 把API Gateway的集成方式从HTTP代理改成Lambda集成,让请求先经过Lambda处理再转发。
示例Lambda代码(Python):
import requests import boto3 import os s3 = boto3.client('s3') def lambda_handler(event, context): # 从S3拉取证书到临时目录 cert_bucket = os.environ['CERT_BUCKET'] cert_file_key = os.environ['CERT_FILE_KEY'] key_file_key = os.environ['KEY_FILE_KEY'] cert_path = '/tmp/client_cert.pem' key_path = '/tmp/client_key.pem' s3.download_file(cert_bucket, cert_file_key, cert_path) s3.download_file(cert_bucket, key_file_key, key_path) # 构造请求到第三方API third_party_url = os.environ['THIRD_PARTY_API_URL'] request_headers = event['headers'] request_body = event['body'] if event.get('body') else None response = requests.post( third_party_url, headers=request_headers, data=request_body, cert=(cert_path, key_path) ) return { 'statusCode': response.status_code, 'headers': dict(response.headers), 'body': response.text }
3. 针对请求头传递证书的场景
如果是把证书内容放在自定义请求头(比如X-Client-Cert)里,需要做两个配置:
- 在API Gateway的资源CORS设置中,把自定义头添加到「允许的请求头」列表,避免跨域拦截。
- 检查集成请求的映射模板,确保没有过滤该头,最简单的方式是用
$input.params().header直接转发所有请求头。
另外要注意API Gateway会自动添加X-Forwarded-For等头,若第三方API对请求头有严格校验,可能需要在映射模板中移除不必要的头。
4. 检查API Gateway的TLS配置
- 确认API Gateway使用的TLS版本(比如TLS 1.2+)和第三方API兼容,避免因协议版本不匹配导致证书验证失败。
- 如果第三方API要求特定的CA证书,需要在API Gateway的「信任存储」中添加对应的CA证书,确保API Gateway能信任第三方API的证书。
5. 调试排查技巧
- 开启API Gateway的CloudWatch日志,查看请求头和参数是否正确传递到后端集成。
- 在Lambda函数中添加日志,打印证书路径、请求参数和第三方API的响应详情,定位具体错误(比如证书格式错误、权限不足等)。
内容的提问来源于stack exchange,提问作者RodriKing
相关产品推荐
相关产品推荐

