如何让Python应用接受两个CA证书以解决SSL验证失败问题
解决办公网络下Python连接Google Calendar的SSL证书验证失败问题
问题概述
办公网络中运行连接Google Calendar的Python应用时,出现SSL证书链验证错误:
google.auth.exceptions.TransportError: HTTPSConnectionPool(host='oauth2.googleapis.com', port=443): Max retries exceeded with url: /token (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1076)')))
已获取公司安全部门提供的两个.pem证书,但之前的配置尝试无效。
之前尝试的问题解析
- SSL上下文配置错误
代码存在笔误(mcontext应为context),且使用了错误的SSL目的:ssl.Purpose.CLIENT_AUTH用于客户端证书验证,而验证服务器证书需要ssl.Purpose.SERVER_AUTH。最重要的是,未将配置好的上下文传递给Google Auth使用的请求会话,导致配置未生效。 verify=False无效
单独调用requests.get(verify=False)仅对该请求生效,Google Auth库内部使用独立的请求会话,不会继承此设置。此外,关闭SSL验证存在安全风险,不适合公司网络环境。
解决方案
方案1:代码中配置自定义SSL上下文(推荐)
步骤1:合并CA证书
将两个.pem证书的内容合并到一个文件中(比如命名为combined_certs.pem),直接复制粘贴即可,顺序不影响。
步骤2:配置请求会话并传递给Google Auth
import ssl import requests from google.auth.transport.requests import Request from googleapiclient.discovery import build # 合并后的CA证书路径(用原始字符串避免转义) CA_CERT_PATH = r"V:\combined_certs.pem" # 创建用于验证服务器证书的SSL上下文 ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ssl_context.load_verify_locations(cafile=CA_CERT_PATH) # 配置requests会话 session = requests.Session() session.verify = CA_CERT_PATH # 刷新凭证时使用该会话 credentials.refresh(Request(session=session)) # 创建Calendar服务时传递自定义会话 service = build( 'calendar', 'v3', credentials=credentials, requestBuilder=lambda **kwargs: requests.Request(session=session, **kwargs) )
方案2:通过环境变量全局配置(无需修改代码)
在Windows系统中,设置以下环境变量之一:
- 设置REQUESTS_CA_BUNDLE:
setx REQUESTS_CA_BUNDLE "V:\combined_certs.pem" - 设置SSL_CERT_FILE:
setx SSL_CERT_FILE "V:\combined_certs.pem"
设置后重启应用,requests和Google Auth库会自动使用指定的CA证书。
注意事项
- 若不想合并证书,也可以将两个证书放在同一目录下,使用
capath参数指定目录路径(需确保目录下的证书已按OpenSSL要求命名),但合并文件是更简单的方式。 - 避免使用
verify=False关闭SSL验证,防止中间人攻击风险。
内容的提问来源于stack exchange,提问作者user22057918
相关产品推荐
相关产品推荐

