Python上传文件至SharePoint遇令牌错误,有限权限下如何解决?
尝试通过Python上传文件至SharePoint,使用的代码如下:
from office365.runtime.auth.user_credential import UserCredential from office365.sharepoint.client_context import ClientContext def get_sharepoint_context_using_user(): sharepoint_url = 'https://companyname.sharepoint.com/sites/Afolder/' user_credentials = UserCredential("login", "password") ctx = ClientContext(sharepoint_url).with_credentials(user_credentials) return ctx def upload_to_sharepoint(file_name: str): sp_relative_url='https://companyname.sharepoint.com/sites/Afolder/some%20thing/Forms/AllItems.aspx' ctx = get_sharepoint_context_using_user() ctx = get_sharepoint_context_using_user() target_folder = ctx.web.get_folder_by_server_relative_url(sp_relative_url) with open(file_name, 'rb') as content_file: file_content = content_file.read() target_folder.upload_file(file_name, file_content).execute_query()
调用上传函数 upload_to_sharepoint(os.path.join(path_from, file_word)) 时,出现错误:
ValueError: Cannot get binary security token for from https://login.microsoftonline.com/extSTS.srf
仅被授予 https://companyname.sharepoint.com/sites/Afolder 路径的访问权限,而非整个SharePoint站点,请问该权限限制是否为错误原因?有限权限下能否通过Python上传文件?
1. 权限限制不是当前错误的直接原因
只要你的账号拥有/sites/Afolder下目标文件夹的上传/编辑权限(比如贡献者、编辑角色),就完全可以通过Python完成上传操作,有限权限本身不阻碍API调用的可行性。
2. 当前错误的核心原因
(1) 目标路径传错了
get_folder_by_server_relative_url要求传入服务器相对路径,不是完整的网页URL。你现在传的sp_relative_url是SharePoint的文件列表页面地址(.../Forms/AllItems.aspx),这不是文件夹的实际路径。正确的相对路径应该是/sites/Afolder/some thing(直接写空格,不用%20编码)。
(2) 冗余的上下文获取
代码里连续两次调用get_sharepoint_context_using_user(),属于没必要的重复操作,虽然不会直接报错,但会浪费资源,建议只调用一次。
(3) 认证环节可能出问题
- 检查账号密码是否正确,如果账号开了MFA(多因素认证),普通账号密码的认证方式会直接失败,得换成应用权限或证书认证。
- 确认
sharepoint_url是站点根地址,格式要准确(比如结尾带斜杠)。
3. 修正后的示例代码
from office365.runtime.auth.user_credential import UserCredential from office365.sharepoint.client_context import ClientContext import os def get_sharepoint_context_using_user(): sharepoint_url = 'https://companyname.sharepoint.com/sites/Afolder/' user_credentials = UserCredential("login", "password") ctx = ClientContext(sharepoint_url).with_credentials(user_credentials) # 可选:验证上下文是否有效 web = ctx.web ctx.load(web) ctx.execute_query() print(f"已连接到站点: {web.properties['Title']}") return ctx def upload_to_sharepoint(file_path: str): # 服务器相对路径,无需完整域名,从/sites开头 sp_folder_relative_url = '/sites/Afolder/some thing' ctx = get_sharepoint_context_using_user() try: target_folder = ctx.web.get_folder_by_server_relative_url(sp_folder_relative_url) file_name = os.path.basename(file_path) with open(file_path, 'rb') as content_file: file_content = content_file.read() target_folder.upload_file(file_name, file_content).execute_query() print(f"文件 {file_name} 上传成功") except Exception as e: print(f"上传失败: {str(e)}") # 调用示例 path_from = "本地文件目录路径" file_word = "目标文件名.docx" upload_to_sharepoint(os.path.join(path_from, file_word))
4. 权限验证补充
如果改完上述问题还是传不了,先手动登录SharePoint网页,在目标文件夹里传个文件试试。如果网页端都传不了,说明是权限配置的问题,得找管理员调整权限;如果网页端能传,再排查代码里的认证或路径细节。
内容的提问来源于stack exchange,提问作者Anastasia

