使用证书认证访问SharePoint Online REST API时遇Auth错误求助
问题排查与修复
错误原因
AuthenticationContext.acquire_token_for_app()方法不支持client_credential关键字参数,该方法仅适配**客户端密钥(Client Secret)**认证场景。- 使用
ClientCredential类传递证书路径是错误的,该类专门用于封装客户端ID和密钥,不处理证书认证逻辑。
修复方案
证书认证需要使用专门的方法读取PFX证书内容,并调用 acquire_token_with_client_certificate 完成认证,步骤如下:
1. 依赖安装
先安装证书处理所需依赖:
pip install cryptography
2. 修正后的函数代码
from office365.runtime.auth.authentication_context import AuthenticationContext from office365.sharepoint.client_context import ClientContext from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend def list_files_in_sharepoint_with_cert(tenant_id, client_id, certificate_path, sharepoint_site_url, sharepoint_folder_url, cert_password=None): """ Lists files in a specified SharePoint folder or entire site using certificate-based authentication. :param tenant_id: Azure AD Tenant ID. :param client_id: The Azure AD application (client) ID. :param certificate_path: Path to the .pfx certificate file. :param sharepoint_site_url: The full URL of the SharePoint site (e.g., https://xxx.sharepoint.com/sites/yyy). :param sharepoint_folder_url: The relative URL of the SharePoint folder (e.g., '/Shared Documents/'). :param cert_password: Optional password for the PFX certificate (as bytes, e.g., b"your_password"). """ try: # 读取PFX证书文件 with open(certificate_path, "rb") as f: pfx_data = f.read() # 解析证书中的私钥和公钥 pkcs12 = serialization.load_pkcs12( pfx_data, password=cert_password, backend=default_backend() ) private_key = pkcs12.private_key cert = pkcs12.certificate # 初始化认证上下文 authority_url = f'https://login.microsoftonline.com/{tenant_id}' auth_ctx = AuthenticationContext(authority_url) # 通过证书获取访问令牌 token_response = auth_ctx.acquire_token_with_client_certificate( resource=sharepoint_site_url, client_id=client_id, certificate=cert.public_bytes(serialization.Encoding.PEM), private_key=private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) ) # 创建SharePoint客户端上下文 ctx = ClientContext(sharepoint_site_url).with_token(token_response) # 读取指定文件夹下的文件列表 folder = ctx.web.get_folder_by_server_relative_url(sharepoint_folder_url) files = folder.files ctx.load(files) ctx.execute_query() # 输出文件信息 for file in files: print(f"文件名: {file.properties['Name']}, 相对路径: {file.properties['ServerRelativeUrl']}") except Exception as e: print(f"An error occurred: {e}")
3. 关键修正点说明
- 替换
acquire_token_for_app为证书认证专用的acquire_token_with_client_certificate方法。 - 使用
cryptography库解析PFX证书,提取私钥和公钥内容(若PFX文件设置了密码,需传入cert_password参数)。 - SharePoint站点URL需传入完整站点地址(如
https://xxx.sharepoint.com/sites/yyy),而非根域名。
4. 调用示例
list_files_in_sharepoint_with_cert( '123456789', '987654321', 'c:\\users\\qqq\\xxx.pfx', 'https://xxx.sharepoint.com/sites/yyy', # 修正为完整站点URL '/Shared Documents/', cert_password=b"your_pfx_password" # 证书无密码可省略该参数 )
内容的提问来源于stack exchange,提问作者BrownInTown
相关产品推荐
相关产品推荐

