使用Python获取Power BI Rest API令牌后调用报表接口遇401错误的解决方法
Power BI REST API 请求返回401错误(已通过MSAL获取令牌)
我编写了以下Python代码用于获取Power BI Rest API的令牌,且似乎已成功获取到令牌,但在请求获取报表列表时,持续收到401错误。我本以为msal能解决这个问题,请问该如何修复?
import msal import requests import json client_id=client_id client_secret=client_secret authority_url = 'https://login.microsoftonline.com/tennet_id' scope = ["https://analysis.windows.net/powerbi/api/.default"] app = msal.ConfidentialClientApplication(client_id,authority=authority_url,client_credential=client_secret) result = app.acquire_token_for_client(scopes=scope) if 'access_token' in result: access_token = result['access_token'] header = {'Content-Type':'application/json','Authorization': f'Bearer {access_token}'} api_out = requests.get(url=url_groups, headers=header) print(api_out.json()) else: print(result.get("error")) print(result.get("error_description")) group_id = group_id url = f"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/reports" headers = { "Authorization": f"Bearer {access_token}" } response = requests.get(url, headers=headers)
我每次请求都会返回401错误。
修复方案
1. 检查Azure AD应用的权限配置
- 确保在Azure AD应用注册中,已为Power BI API添加应用权限(而非委派权限),且完成了管理员同意。至少需要
Report.Read.All或Report.ReadWrite.All权限,若针对特定工作区,需确保权限覆盖目标工作区。 - 使用
/.default范围会自动包含所有已配置的应用权限,若权限未配置或未完成管理员同意,令牌会缺少必要权限声明,导致API拒绝请求。
2. 验证令牌的有效性
- 将获取到的
access_token用JWT解码工具解析,检查以下内容:aud(受众)是否为https://analysis.windows.net/powerbi/api,避免拼写错误。roles字段是否包含所需权限(如Report.Read.All),无此字段说明权限配置或同意步骤有误。exp(过期时间)是否在当前时间之后,避免使用过期令牌。
3. 确认工作区访问权限
- 即使应用有全局权限,仍需确保Power BI工作区(Group)已将该Azure AD应用添加为成员或管理员。进入工作区设置的「访问权限」,添加应用注册名称并分配对应角色。
4. 修正代码中的潜在问题
- 代码中
url_groups未定义,且先发起了未明确的请求,若该请求出错可能导致后续access_token未正确赋值。调整代码逻辑,确保令牌有效后再执行报表请求:import msal import requests client_id = "<你的客户端ID>" client_secret = "<你的客户端密钥>" tenant_id = "<你的租户ID>" authority_url = f'https://login.microsoftonline.com/{tenant_id}' scope = ["https://analysis.windows.net/powerbi/api/.default"] app = msal.ConfidentialClientApplication(client_id, authority=authority_url, client_credential=client_secret) result = app.acquire_token_for_client(scopes=scope) if 'access_token' in result: access_token = result['access_token'] group_id = "<你的工作区ID>" url = f"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/reports" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } response = requests.get(url, headers=headers) print(response.status_code) print(response.json()) else: print(result.get("error")) print(result.get("error_description")) - 修正
tennet_id的拼写错误为tenant_id,确保租户ID正确。
5. 验证API端点参数
- 确认
group_id是有效的工作区ID,避免因资源不存在导致API返回401(部分场景下权限不足和资源不存在都会返回401,需仔细区分)。
内容的提问来源于stack exchange,提问作者Дмитрий Эдуардович
相关产品推荐
相关产品推荐

