如何在Python的OpenAPI3中配置mTLS连接服务器
问题:如何向OpenAPI3客户端提供双向TLS密钥对?
我有一台实现了abis.yaml的服务器,该服务器配置为使用双向TLS(mTLS)——作为客户端,我需要信任库(truststore)和密钥对(keypair)才能连接,但abis.yaml未标注该安全方式。
我不清楚如何向OpenAPI3提供密钥对,我认为需要使用持久化的requests.Session,但不知道如何传入该会话。
失败示例代码
from requests import Session import yaml from openapi3 import OpenAPI # load the spec file and read the yaml with open('abis.yaml') as f: spec = yaml.safe_load(f.read()) # parse the spec into python - this will raise if the spec is invalid req: Session = Session() req.cert = ( "otsbms.pem", "otsbms.key.pem" ) req.verify = 'ca.pem' req.request(method= 'DELETE', url='https://192.168.101.41/brs/v1/persons/P1?transactionId=guid',) # the line above returns '500' meaning the https connection was successful, and the abis server did not understand my request, which is another problem outside the scope of this question. api = OpenAPI(raw_document=spec, ssl_verify='ca.pem', use_session=True, session_factory=Session) api.servers[0].url = 'https://192.168.101.41/' # api.authenticate( "mutualTLS", ( "otsbms.pem", "otsbms.key.pem" ) ) # call operations and receive result models result = api.call_deleteAll(parameters={"personId": "a123", "transactionId": "a456", },session=req)
报错信息
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.101.41', port=443): Max retries exceeded with url: //v1/persons/a123?transactionId=a456 (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:997)')))
解决方法
问题出在OpenAPI实例的会话配置逻辑上——你之前创建的带证书的Session没有被OpenAPI正确复用。正确的做法是提前配置好mTLS证书的Session,通过session_factory传入OpenAPI实例,确保所有请求都使用这个已配置的会话。
修正后的代码
from requests import Session import yaml from openapi3 import OpenAPI # 加载OpenAPI规范 with open('abis.yaml') as f: spec = yaml.safe_load(f.read()) # 配置带有双向TLS证书的Session client_session = Session() # 设置客户端证书和密钥对 client_session.cert = ("otsbms.pem", "otsbms.key.pem") # 设置信任的CA证书 client_session.verify = 'ca.pem' # 创建OpenAPI实例时,复用已配置好的Session api = OpenAPI( raw_document=spec, use_session=True, # 用lambda返回已配置的Session,确保所有请求复用该会话 session_factory=lambda: client_session ) # 替换服务器地址 api.servers[0].url = 'https://192.168.101.41/' # 调用API操作 result = api.call_deleteAll(parameters={"personId": "a123", "transactionId": "a456"})
关键说明
- 会话复用逻辑:OpenAPI的
session_factory参数用于生成请求会话,直接返回你提前配置好的带证书的Session,就能确保所有API请求都使用正确的mTLS配置。 - 避免重复配置:不需要再设置
ssl_verify参数,因为Session已经配置了verify,会话会优先使用自身的SSL配置。 - 原代码错误点:之前用
session_factory=Session会生成全新的未配置证书的Session,而call方法传入的session参数未被库正确复用,导致请求没有携带客户端证书,触发服务器的证书验证错误。
内容的提问来源于stack exchange,提问作者malabile
相关产品推荐
相关产品推荐

