Python中使用客户端证书认证获取令牌失败,求可行代码方案
客户端证书认证获取Microsoft Graph令牌(替代客户端密钥)
原客户端密钥认证实现回顾
我们已通过以下步骤实现客户端密钥认证获取令牌:
- 在Azure门户中注册应用程序,获取Client ID和Client Secret
- 添加Microsoft Graph权限并获得管理员同意
对应的Python代码:
from msal import ConfidentialClientApplication client_id = "xxxxxx" client_secret = "yyyyyyy" tenant_id = "zzzzzzz" authority_url = f"https://login.microsoftonline.com/{tenant_id}" app = ConfidentialClientApplication( client_id=client_id, client_credential=client_secret, authority=authority_url ) scope = "https://graph.microsoft.com/.default" result = app.acquire_token_for_client(scopes=scope) access_token = result.get("access_token") print(access_token)
客户端证书认证实现方案
Azure门户前置配置
- 进入Azure AD应用注册的证书和密码选项卡,点击上传证书,上传你的PFX或CER格式证书,上传后记录证书的指纹(Thumbprint)
- 确保已完成Microsoft Graph权限添加及管理员同意(与原步骤一致)
Python代码实现
使用MSAL库加载证书完成认证,以下提供两种常见证书加载方式:
方式1:加载PFX格式证书(带密码)
from msal import ConfidentialClientApplication import os client_id = "xxxxxx" tenant_id = "zzzzzzz" authority_url = f"https://login.microsoftonline.com/{tenant_id}" # 证书路径及密码 pfx_path = os.path.abspath("your_certificate.pfx") pfx_password = "your_pfx_password" # 初始化ConfidentialClientApplication,传入证书信息 app = ConfidentialClientApplication( client_id=client_id, client_credential={"pfx": pfx_path, "password": pfx_password}, authority=authority_url ) scope = "https://graph.microsoft.com/.default" result = app.acquire_token_for_client(scopes=scope) if "access_token" in result: access_token = result["access_token"] print(access_token) else: print(f"认证失败: {result.get('error_description')}")
方式2:加载PEM格式证书(分离的私钥和公钥)
from msal import ConfidentialClientApplication import os client_id = "xxxxxx" tenant_id = "zzzzzzz" authority_url = f"https://login.microsoftonline.com/{tenant_id}" # 私钥和证书路径 private_key_path = os.path.abspath("private_key.pem") certificate_path = os.path.abspath("certificate.pem") # 读取私钥和证书内容 with open(private_key_path, "r") as f: private_key = f.read() with open(certificate_path, "r") as f: certificate = f.read() app = ConfidentialClientApplication( client_id=client_id, client_credential={"private_key": private_key, "thumbprint": "你的证书指纹", "public_certificate": certificate}, authority=authority_url ) scope = "https://graph.microsoft.com/.default" result = app.acquire_token_for_client(scopes=scope) if "access_token" in result: access_token = result["access_token"] print(access_token) else: print(f"认证失败: {result.get('error_description')}")
关键说明
- 确保证书已正确上传至Azure应用注册,且指纹与代码中填写的一致
- MSAL库会自动处理证书签名流程,无需手动实现JWT签名
- 若认证失败,可通过
result中的error和error_description字段排查问题
内容的提问来源于stack exchange,提问作者Zayn Lauren
相关产品推荐
相关产品推荐

