python - aiohttp 和客户端 SSL 证书

标签 python ssl certificate client-certificates aiohttp

我最近从 flask + requests 转移到 aiohttp 及其异步 http 客户端。

在我的场景中,我需要通过 HTTPS(使用自定义证书)调用 API 并发送客户端证书。

对于第一部分(验证自定义证书),支持很明确clearly documented int the docs效果很好。

另一方面,对于第二部分,我似乎无法找到一种简单的方法来附加自定义 SSL 客户端证书来授权客户端。

你们知道怎么做吗?非常感谢!

最佳答案

编辑:我已经提交了 PR更新了有关该主题的 aiohttp 文档,并且已将其合并。

对于将来可能遇到此问题的任何人..

TL:DR

import ssl
import aiohttp    

ssl_ctx = ssl.create_default_context(cafile='/path_to_client_root_ca')
ssl_ctx.load_cert_chain('/path_to_client_public_key.pem', '/path_to_client_private_key.pem')

conn = aiohttp.TCPConnector(ssl_context=ssl_ctx)
session = aiohttp.ClientSession(connector=conn)

# session will now send client certificates..

长话短说 - 我查看了它是如何在请求中实现的(它巧妙地记录了 API here ),显然它是在 urllib3 中实现的。

urllib3 将 cert 参数一直向下传递到它的 HTTPSConnection对象,最终调用此函数的地方:

...
self.sock = ssl_wrap_socket(
    sock=conn,
    keyfile=self.key_file,
    certfile=self.cert_file,
    ssl_context=self.ssl_context,
)
...

它的作用是:

...
if ca_certs or ca_cert_dir:
    try:
        context.load_verify_locations(ca_certs, ca_cert_dir)
    except IOError as e:  # Platform-specific: Python 2.6, 2.7, 3.2
        raise SSLError(e)
    # Py33 raises FileNotFoundError which subclasses OSError
    # These are not equivalent unless we check the errno attribute
    except OSError as e:  # Platform-specific: Python 3.3 and beyond
        if e.errno == errno.ENOENT:
            raise SSLError(e)
        raise
elif getattr(context, 'load_default_certs', None) is not None:
    # try to load OS default certs; works well on Windows (require Python3.4+)
    context.load_default_certs()

if certfile:
    context.load_cert_chain(certfile, keyfile)
if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
    return context.wrap_socket(sock, server_hostname=server_hostname)
...

这里有趣的调用是 load_cert_chain - 这意味着如果我们只是创建一个 ssl.SSLContext(这是一个标准库接口(interface))对象并调用 load_cert_chain 使用我们的客户端证书,aiohttp 的行为与 requests\urllib3 相同。

因此,尽管 aiohttp 的文档没有告诉您这一点,但它们确实指定您可以加载自己的 ssl.SSLContext

关于python - aiohttp 和客户端 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41701791/

相关文章:

python - 有新的/更新的斜纹布吗?

Docker 容器失败,因为 x.cert 权限被拒绝

ssl - Spring SAML + ADFS : Response doesn't have any valid assertion which would pass subject validation

ruby - 为什么 Ruby 无法验证 SSL 证书?

python - 在 Python 中按顺序将 JSON 对象写回 .json 文件

python - lxml etree.parse.xpath() 返回仅包含制表符和换行符的项目

java - jetty SslContextFactory : Print all allowed cipher suites

ios - 更新配置分布配置文件

node.js - 是否可以使用 node.js 和加密来签署 Passbook list ?

python - MPI4Py 分散 sendbuf 参数类型?