使用Python客户端库访问带企业CA签名证书的Minio遇错
解决Minio Python客户端使用Windows证书存储CA时的TypeError问题
问题原因
你遇到的TypeError: unhashable type: list错误,核心是urllib3的PoolManager中ca_certs参数的预期值和你传入的类型不匹配:
ca_certs要求的是磁盘上CA证书文件的路径字符串(比如"C:/certs/rootCA.pem");- 而
ssl.get_ca_certs()返回的是证书对象的列表,直接传入会触发类型错误。
另外其实你不需要手动构建urllib3的PoolManager——Minio Python客户端支持直接传入ssl.SSLContext对象,这能更简洁地利用Windows系统证书存储。
解决方案1:直接使用SSL上下文(推荐)
ssl.create_default_context()会自动加载Windows系统证书存储中的根CA,你可以直接把这个上下文传给Minio客户端,无需手动处理证书列表:
import ssl from minio import Minio # 创建默认SSL上下文,自动加载系统信任的所有CA(包括Windows证书存储) ssl_context = ssl.create_default_context() # 初始化Minio客户端,传入ssl_context s3dev = Minio( "s3dev.mycorp.com:9000", access_key="myAccessKey", secret_key="mySecretKey", secure=True, ssl_context=ssl_context ) # 测试上传(示例) s3dev.fput_object("my-bucket", "remote-file.txt", "local-file.txt")
这种方式最简洁,也能保证自动使用系统信任的CA,避免手动导出证书的麻烦。
解决方案2:手动处理证书列表(如果必须用urllib3 PoolManager)
如果你一定要自己构建urllib3的PoolManager,需要将get_ca_certs()返回的证书列表转换成PEM格式的文件,再传入ca_certs参数:
import ssl import tempfile import urllib3 import os from minio import Minio # 获取系统CA证书列表 ssl_context = ssl.create_default_context() ca_certs = ssl_context.get_ca_certs() # 将证书列表转换为PEM格式字符串 pem_content = "" for cert in ca_certs: # 将DER格式证书转为PEM pem_content += ssl.DER_cert_to_PEM_cert(cert["DER"]) + "\n" # 创建临时PEM文件 with tempfile.NamedTemporaryFile(mode="w", suffix=".pem", delete=False) as temp_file: temp_file.write(pem_content) temp_cert_path = temp_file.name # 构建urllib3 PoolManager http_client = urllib3.PoolManager( cert_reqs="CERT_REQUIRED", ca_certs=temp_cert_path ) # 初始化Minio客户端 s3dev = Minio( "s3dev.mycorp.com:9000", access_key="myAccessKey", secret_key="mySecretKey", secure=True, http_client=http_client ) # 操作完成后删除临时文件(可选) os.unlink(temp_cert_path)
补充:为什么S3 Browser能正常访问?
S3 Browser默认会读取Windows系统证书存储中的信任CA,所以它能自动验证你的Minio实例证书;而你的Python代码错误地将证书列表直接传给了urllib3,导致类型不匹配。
内容的提问来源于stack exchange,提问作者nojetlag
相关产品推荐
相关产品推荐

