使用 Office365-REST-Python-Client 使用 Azure AD App-Only 访问 SharePoint Online 站点时出现错误 AADSTS500011

Error AADSTS500011 accessing SharePoint Online site with Azure AD App-Only using Office365-REST-Python-Client

我正在尝试使用 Azure AD App-Only 连接到 SharePoint Online 网站。我正在使用 Office365-REST-Python-Client v2.3.5 (https://github.com/vgrem/Office365-REST-Python-Client).

我已按照以下 link 的说明通过 Azure AD App-Only 授予访问权限:https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread。 API 权限 Sites.FullControl.All 已通过 Microsoft Azure 门户中的“应用程序权限”授予我的应用程序。我还确保管理员同意已授予 API 权限。

我能够成功访问我的 SharePoint Online 根站点 https://{my_tenant_name}.sharepoint.com 并将文件上传到文档库“Documents”,没有任何问题。但是,如果我尝试访问另一个 SharePoint Online 网站 https://{my_tenant_name}.sharepoint.com/sites/test,而不是我的根网站,我会收到以下错误:

“AADSTS500011:在名为 {tenant_guid} 的租户中找不到名为 https://{my_tenant_name}.sharepoint.com/sites/test 的资源主体。如果该应用程序尚未由租户管理员安装或未经租户中任何用户同意。您可能已将身份验证请求发送给错误的租户。"

我已经仔细检查了 SharePoint Online 网站 url、租户 guid 和 API 权限,包括管理员的同意,但我不确定是什么导致了错误。

下面是我可以重现问题的代码:

from office365.sharepoint.client_context import ClientContext

# Access to the SharePoint Online root site works
# site_url = 'https://{my_tenant_name}.sharepoint.com'
# Other than SharePoint Online root site gives AADSTS500011 error
site_url = 'https://{my_tenant_name}.sharepoint.com/sites/test'
app_settings = {
    'tenant': '{my_tenant_name}.onmicrosoft.com',
    'client_id': '<$guid>',
    'thumbprint': "<$base64CertHash>",
    'certificate_path': 'selfsigned_certificate.pem',
}
ctx = ClientContext(site_url).with_client_certificate(
    app_settings.get('tenant'),
    app_settings.get('client_id'),
    app_settings.get('thumbprint'),
    app_settings.get('certificate_path')
)
current_web = ctx.web
ctx.load(current_web)
ctx.execute_query()
print("current_web.url: {}".format(current_web.url))

尝试为应用程序授予以下 API 权限:

  • Files.ReadWrite.All
  • Sites.ReadWrite.All

通过此访问,我们能够使用 Microsoft Graph API 中的 SharePoint 功能。我们使用以下代码获取令牌:

import msal

# Get a token
auth = f'https://login.microsoftonline.com/{tenant_id}'
app = msal.ConfidentialClientApplication(
    client_id, authority=auth, client_credential=client_secret)
result = app.acquire_token_for_client(scopes=['https://graph.microsoft.com/.default'])

token = result['access_token']

检索列表如下所示 (ref):

import requests
# Define the headers of the request
headers = {'Authorization': "Bearer " + token}

# Make the GET request to the Graph API to get the list
resp = requests.get(
    'https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_title}',
    headers=headers
).json()

print(resp)