如何从Python Azure函数应用使用Azure密钥保管库证书发送HTTPS请求
从Azure函数应用使用Key Vault中的PKCS12证书发送HTTPS请求
问题背景
本地通过磁盘加载PKCS12证书文件发送HTTPS请求时运行正常,但在Azure函数中使用Azure密钥保管库(Key Vault)存储的证书时,无法直接通过文件路径传入Pkcs12Adapter,需要将Key Vault中的证书转换为字节流传入pkcs12_data参数。
本地测试正常的代码:
from requests import Session from requests_pkcs12 import Pkcs12Adapter url = 'https://example/api/profile' with Session() as s: s.mount(url, Pkcs12Adapter(pkcs12_filename='cert.pfx', pkcs12_password='cert_password')) r = s.get(url, verify='ca_cert.pem') print(r.status_code) print(r.text)
已完成的Key Vault证书/密码获取代码(可正常运行):
from requests import Session from requests_pkcs12 import Pkcs12Adapter from azure.keyvault.certificates import CertificateClient from azure.keyvault.secrets import SecretClient from azure.identity import DefaultAzureCredential import logging pkcs12_name = 'cert_name' pkcs12_pass_name = 'cert_password_name' vault_name = 'vault-name' credential = DefaultAzureCredential() cert_client = CertificateClient(f"https://{vault_name}.vault.azure.net/", credential) cert = cert_client.get_certificate(pkcs12_name) secret_client = SecretClient(f"https://{vault_name}.vault.azure.net/", credential) secret = secret_client.get_secret(pkcs12_pass_name) # 调试日志 logging.info('--== PKCS12 DETAILS ==--') logging.info(cert.name) logging.info(cert.properties.version) logging.info('--== SECRET DETAILS ==--') logging.info(secret.name) logging.info(secret.properties)
解决方案
关键注意点:
CertificateClient.get_certificate()返回的是证书的元数据对象,并非PKCS12格式的字节流。Key Vault中创建证书时,会自动生成一个同名的Secret,该Secret的值是Base64编码的PKCS12字节流。- 需要通过
SecretClient获取该同名Secret,解码后得到PKCS12字节流。
修改后的完整代码:
from requests import Session from requests_pkcs12 import Pkcs12Adapter from azure.keyvault.secrets import SecretClient from azure.identity import DefaultAzureCredential import base64 import logging pkcs12_name = 'cert_name' pkcs12_pass_name = 'cert_password_name' vault_name = 'vault-name' url = 'https://example/api/profile' credential = DefaultAzureCredential() # 获取PKCS12证书的Base64编码Secret secret_client = SecretClient(f"https://{vault_name}.vault.azure.net/", credential) # 获取证书对应的PKCS12格式Secret(和证书同名) cert_secret = secret_client.get_secret(pkcs12_name) # Base64解码为字节流 pkcs12_bytes = base64.b64decode(cert_secret.value) # 获取证书密码 password_secret = secret_client.get_secret(pkcs12_pass_name) pkcs12_password = password_secret.value # 发送HTTPS请求 with Session() as s: s.mount(url, Pkcs12Adapter(pkcs12_data=pkcs12_bytes, pkcs12_password=pkcs12_password)) r = s.get(url, verify='ca_cert.pem') print(r.status_code) print(r.text)
补充说明
- 确保Azure函数的托管身份拥有Key Vault的
Secret Get权限,因为需要读取证书对应的Secret和密码Secret。 - 如果CA证书也存储在Key Vault中,同样可以通过SecretClient获取后写入临时文件,再传入
verify参数;部分版本的requests支持直接传入CA证书的字节流,可根据实际情况调整。
内容的提问来源于stack exchange,提问作者ABF
相关产品推荐
相关产品推荐

