代码之家  ›  专栏  ›  技术社区  ›  malabile

如何使用openapi3-python使用双向身份验证(mTLS)连接到服务器

  •  0
  • malabile  · 技术社区  · 2 年前

    我有一个服务器,它实现 https://osia.readthedocs.io/en/stable/abis.yaml < 该服务器被配置为使用双向TLS(作为客户端,我需要有一个信任库和一个密钥对来连接到服务器)。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)
    

    结果是:我几乎在我的ca.pem很好,但服务器在挑战密钥对时确实失败了。 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)')))

    0 回复  |  直到 2 年前
        1
  •  0
  •   malabile    2 年前

    事实证明openapi3是一个大部分处于非活动状态的项目。使用 aiopenapi3 是一个更好的解决方案。

    以下是的答案 ticket :

    你好

    对我来说,你的方法基本上是有效的。请求:请求类确实存在 没有.cert属性,它是由openapi3在mutualTLS时添加的 被请求。必须将(客户端证书/密钥元组)传递给 请求:会话.request()或请求。Session.send-就像你做的那样。如果 未设置mutualTLS,它失败,因为属性不存在可能 解决方法:

    result = session.send(self._request.prepare(), 
        verify=verify, 
        cert=getattr(self._request, "cert", None)) Unlikely this has been working properly.
    

    我在aiopenapi3中分享了这个问题,实际上是同一个问题,尽管 它是请求与httpx的对比。这是我的看法。

    由于所需的asgi tls扩展未在中实现 hypercorn/uvloop和FastAPI不知道mutualTLS-单元测试 非常有趣。