如何用Python通过账号密码程序化认证Microsoft Graph API并访问SharePoint Excel
嘿,刚好我对这个场景很熟悉,来帮你一步步梳理清楚!你提到的两种认证方式都能实现需求,但适用场景和安全性有区别,下面我分别拆解说明,再给你具体的代码示例。
一、先搞懂两种认证方式的差异
- 授权码流程(交互式登录弹窗):这是微软推荐的标准方式,安全性高,适合需要用户手动确认登录的场景。注册应用后,运行时会弹出浏览器让用户输入账号密码,权限方面如果是委托权限(Delegated),普通用户自己就能授权,不需要管理员审批;如果是应用权限(Application)才需要管理员同意。
- 资源所有者密码凭据(ROPC)流程:就是你想的用用户名密码直接程序化登录,不用弹窗。但这种方式不推荐用于生产环境——因为要明文处理用户密码,存在泄露风险,而且不支持开启了MFA(多因素认证)的账户。不过对于内部测试、无人值守的自动化脚本,倒是可以临时用用。
二、Azure AD应用注册的前置步骤(两种方式都需要做)
不管选哪种认证,都得先在Azure AD里注册一个应用:
- 登录Azure门户,找到「Azure Active Directory」→「应用注册」→「新注册」。
- 填个应用名称,账户类型选「任何组织目录中的帐户」(根据你的实际场景调整);如果用授权码流程,要填重定向URI(选Web类型,比如
http://localhost:8000/callback),ROPC流程可以不用填。 - 注册完成后,把**客户端ID(Client ID)和租户ID(Tenant ID)**记下来,后面代码要用到。
- 配置权限:进入应用的「API权限」→「添加权限」→ 选「Microsoft Graph」:
- 授权码流程:添加委托权限,比如
Files.ReadWrite.All、Sites.ReadWrite.All(根据你要读写Excel的需求选最小权限),如果是组织账户,可能需要点击「授予管理员同意」。 - ROPC流程:同样加委托权限(因为是模拟用户操作),也需要授予管理员同意。
- 授权码流程:添加委托权限,比如
- 要是用ROPC流程,还要开启公共客户端流:进入「身份验证」→「高级设置」→ 把「允许公共客户端流」设为「是」。
三、Python代码实现
先安装依赖库:
pip install msgraph-core python-dotenv pandas
(pandas是用来方便处理Excel数据,如果你不需要的话可以不用装)
方式1:授权码流程(交互式登录)
from msgraph.core import GraphClient from azure.identity import AuthorizationCodeCredential import pandas as pd import os from dotenv import load_dotenv # 加载环境变量(建议把敏感信息存在.env文件里,不要硬编码) load_dotenv() CLIENT_ID = os.getenv("CLIENT_ID") TENANT_ID = os.getenv("TENANT_ID") REDIRECT_URI = os.getenv("REDIRECT_URI") # 初始化凭据,会自动弹出浏览器让用户登录 credential = AuthorizationCodeCredential( tenant_id=TENANT_ID, client_id=CLIENT_ID, redirect_uri=REDIRECT_URI, authorization_url="https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize", ) # 创建Graph客户端 client = GraphClient(credential=credential) # 示例:读取SharePoint上的Excel数据 # 先获取你的站点ID、Drive ID、文件Item ID,可以通过Graph Explorer查询获取 site_id = "你的站点ID" drive_id = "你的Drive ID" item_id = "Excel文件的Item ID" # 获取Sheet1的已用区域数据 response = client.get(f"/sites/{site_id}/drives/{drive_id}/items/{item_id}/workbook/worksheets/Sheet1/usedRange") data = response.json() # 转成DataFrame方便查看处理 df = pd.DataFrame(data["values"][1:], columns=data["values"][0]) print(df) # 示例:写入单元格(更新A1的值) update_data = {"values": [["这是通过授权码流程更新的内容"]]} client.patch(f"/sites/{site_id}/drives/{drive_id}/items/{item_id}/workbook/worksheets/Sheet1/range(address='A1')", json=update_data)
方式2:ROPC流程(用户名密码程序化登录)
from msgraph.core import GraphClient from azure.identity import UsernamePasswordCredential import pandas as pd import os from dotenv import load_dotenv # 加载环境变量 load_dotenv() CLIENT_ID = os.getenv("CLIENT_ID") TENANT_ID = os.getenv("TENANT_ID") USERNAME = os.getenv("USERNAME") # 格式:user@你的租户域名.onmicrosoft.com PASSWORD = os.getenv("PASSWORD") # 用用户名密码初始化凭据 credential = UsernamePasswordCredential( tenant_id=TENANT_ID, client_id=CLIENT_ID, username=USERNAME, password=PASSWORD ) # 创建Graph客户端 client = GraphClient(credential=credential) # 读取Excel数据(和上面逻辑一样) site_id = "你的站点ID" drive_id = "你的Drive ID" item_id = "Excel文件的Item ID" response = client.get(f"/sites/{site_id}/drives/{drive_id}/items/{item_id}/workbook/worksheets/Sheet1/usedRange") data = response.json() df = pd.DataFrame(data["values"][1:], columns=data["values"][0]) print(df) # 示例:写入单元格(更新B2的值) update_data = {"values": [["这是通过ROPC流程更新的内容"]]} client.patch(f"/sites/{site_id}/drives/{drive_id}/items/{item_id}/workbook/worksheets/Sheet1/range(address='B2')", json=update_data)
四、关键注意事项
- ROPC的坑:如果你的账户开了MFA,ROPC直接失败,这是微软的限制;另外生产环境千万别用,密码泄露风险太高。
- 权限最小化:别贪方便选最大的权限,比如只需要读Excel就选
Files.Read.All,避免过度授权。 - 如何获取Site/Drive/Item ID:可以用Graph Explorer(微软官方的在线工具)来查询,比如查站点列表用
GET /sites,或者通过站点URL获取:GET /sites/yourtenant.sharepoint.com:/sites/yoursite:,返回结果里的id就是站点ID。 - Excel操作API:更多读写操作可以参考Microsoft Graph的Workbook API文档,比如创建工作表、批量更新单元格等都有对应的端点。
内容的提问来源于stack exchange,提问作者hsluoyz
相关产品推荐
相关产品推荐

