首页 > 解决方案 > 尝试导出 powerbi 报告时出现 401 错误代码

问题描述

我可以使用 powerbi 的默认范围获取令牌(“范围”:“https://analysis.windows.net/powerbi/api/.default”])

使用该令牌,我可以读取我的用户有权访问的工作区(“https://api.powerbi.com/v1.0/myorg/groups”)以及每个工作区中的报告信息(“https ://api.powerbi.com/v1.0/myorg/reports/")

但是,如果我重复使用相同的令牌或只是获得一个全新的令牌并不重要,如果我尝试导出特定的报告,我会得到一个 401 错误代码。这就是我发出 requests.get 的方式

 token_ = <new token or reused from previous get requests> 
 reports = requests.get(  # Use token to call downstream service
      config['reports']+report_id+'/Export',
      headers={'Authorization': 'Bearer ' + token_ },)

现在,如果我去https://docs.microsoft.com/en-us/rest/api/power-bi/reports/getreportsingroup
并登录(使用我在 python 脚本上使用的同一用户)。从该页面获取令牌并将其用于我的脚本。它有效,如果我在邮递员中使用它,它有效我尝试在邮递员中使用我的脚本获取的令牌,我也会收到 401 错误。所以,是的,我的脚本没有为这个特定的入口点获取正确的令牌,但对于组和报告入口点来说已经足够了。

我需要在这个特定入口点的令牌请求中添加什么吗?

非常感谢,安德烈斯

这是我正在使用的完整脚本,还有一个 params.json,如下所示:

{
    "authority": "https://login.microsoftonline.com/1abcdefg-abcd-48b6-9b3c-bd5123456",
    "client_id": "5d2545-abcd-4765-8fbb-53555f2fa91",
    "username":"myusername@tenant",
    "password": "mypass",
    "scope" : ["https://analysis.windows.net/powerbi/api/.default"],
    "workspaces" : "https://api.powerbi.com/v1.0/myorg/groups",
    "reports": "https://api.powerbi.com/v1.0/myorg/reports/"

}


#script based on msal github library sample
import sys  # For simplicity, we'll read config file from 1st CLI param sys.argv[1]
import json
import logging
import requests
import msal

def exportReport(report_id,token_):
        result = app.acquire_token_by_username_password( config["username"], config["password"], scopes=config["scope"])
        token_ = result['access_token']
        print(f'Using token: {token_}')
        reports = requests.get(  # Use token to call downstream service
          config['reports']+report_id+'/Export',
          headers={'Authorization': 'Bearer ' + token_ },)
        print(f'-reports: {reports.status_code}')

def list_reports(workspace_id,ws_id,ws_name,token_):
    print(f'reports id for workspace {ws_name}')
    for rp in workspace_id['value']:
        if rp["id"] == "1d509119-76a1-42ce-8afd-bd3c420dd62d":
          exportReport("1d509119-76a1-42ce-8afd-bd0c420dd62d",token_)

def list_workspaces(workspaces_dict):
    for ws in workspaces_dict['value']:
        yield (ws['id'],ws['name'])

config = json.load(open('params.json'))

app = msal.PublicClientApplication(
    config["client_id"], authority=config["authority"],
    )

result = None

if not result:
    logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
    result = app.acquire_token_by_username_password(
        config["username"], config["password"], scopes=config["scope"])

if "access_token" in result:
    workspaces = requests.get(  # Use token to call downstream service
        config['workspaces'],
        headers={'Authorization': 'Bearer ' + result['access_token']},).json()
    ids=list_workspaces(workspaces) #prepare workspace generator
    headers = {'Authorization': 'Bearer ' + result['access_token']}
    while True:
      try:
        ws_id,ws_name=next(ids)
        reports = requests.get(  # Use token to call downstream service
          config['workspaces']+'/'+ws_id+'/reports',
          headers={'Authorization': 'Bearer ' + result['access_token']},).json()
        list_reports(reports,ws_id,ws_name,result['access_token'])
      except StopIteration: 
        exit(0)
else:
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))  # You may need this when reporting a bug
    if 65001 in result.get("error_codes", []): 
        # AAD requires user consent for U/P flow
        print("Visit this to consent:", app.get_authorization_request_url(config["scope"]))

标签: pythonazure-active-directorypowerbimsal

解决方案


根据您的描述,我想您没有为代码中用于登录您的用户帐户的 AD 应用授予正确的权限,请按照以下步骤操作。

导航到 Azure 门户 -> Azure Active Directory-> App registrations-> 找到您在代码中使用的 AD 应用程序(使用 过滤All applications)-> ->在API 中API permissions添加Report.Read.All 委托权限Power BI Service(此权限仅用于读取操作,如果您需要进一步的写入操作,选择Report.ReadWrite.All) ->Grant admin consent for xxx最后单击按钮。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

更新:

使用application idGet-PowerBIAccessToken解决问题中获得的访问令牌。


推荐阅读