【问题标题】:401 error code when trying to export powerbi reports尝试导出 powerbi 报告时出现 401 错误代码
【发布时间】:2021-05-27 07:12:16
【问题描述】:

我可以使用 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 错误代码。这就是我发出请求的方式。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 脚本上使用的同一用户)。从该页面获取令牌并将其用于我的脚本。它有效,如果我在邮递员中使用它,它有效 我尝试在 Postman 中使用我的脚本获取的令牌,我也收到 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"]))

【问题讨论】:

  • 请出示您用于获取令牌的代码。

标签: python azure-active-directory powerbi msal


【解决方案1】:

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

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

更新:

使用从Get-PowerBIAccessToken获取的访问令牌的application id解决问题。

【讨论】:

  • 非常感谢您的描述性回答。我今天休息,但明天一大早我会按照您的建议进行汇报。
  • 早安喜悦,我已经在我的应用程序上获得了该权限。我的用户已经获得了管理员的同意。这就是我能够使用我的脚本阅读报告和工作区的方式。这些是我当前对应用程序的 API 权限:Power BI 服务:App.Read.All、CapacityReadAll、Dashboard.Read.All、Dataflow.Read.All、Dataset.Read.All、Gateway。 Read.All、Report.Read.All、StorageAcount.Read.All、Tenant.Read.All、Workspace.ReadAll。它们都已授予我的用户。
  • 我编辑了原始帖子以包含我用于身份验证的脚本和 json 文件。
  • @MisterWalrus 将您的令牌粘贴到此页面jwt.io,然后查看scp 声明是否包含Report.Read.All 权限。
  • @MisterWalrus 没有这样的功能,在我的回答中更新了你的评论。
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 2013-06-21
相关资源
最近更新 更多