在 Microsoft Graph Python 中访问用户许可证信息时出现授权错误

问题描述 投票:0回答:1

我正在使用 Microsoft Graph Python SDK 来访问用户许可证信息。这是代码行:

license_details = await graph_client.users.by_user_id(user_id).license_details.get()

但是,这会不断抛出授权错误并显示以下响应:

APIError
  Code: 403
  message: None
  error: MainError(additional_data={}, code='Authorization_RequestDenied', details=None, inner_error=InnerError(additional_data={}, client_request_id='a0dc5684-d627-477b-af2c-1d264039e6de', date=DateTime(2024, 11, 13, 5, 59, 28, tzinfo=Timezone('UTC')), odata_type=None, request_id='f503re17-615b-46f4-afce-fc02bda244a2'), message='Insufficient privileges to complete the operation.', target=None)

我的应用程序拥有所有必要的权限,例如 User.Read.All 和 Directory.Read.All,并获得管理员同意并使用正确的凭据。尽管如此,错误仍然发生。

目标是检索用户的许可证详细信息,但实际上返回了 403 授权错误。访问许可证详细信息是否需要额外的权限? Azure AD 应用程序配置是否存在问题?

预先感谢您的帮助!

azure microsoft-graph-api microsoft-graph-sdks
1个回答
0
投票

请注意,

licenseDetails
API 端点不支持 Application 类型的权限。您可以参考这个MS Document

最初,当我尝试使用授予 Application 类型权限的客户端凭据流程访问用户的许可证信息时,我也遇到了 同样的错误

enter image description here

要解决该错误,请通过授予 Deleated 类型的

LicenseAssignment.ReadWrite.All
权限,切换到 deleated 流程,例如交互式或授权代码流程:

enter image description here

在我的例子中,我使用了交互流,其重定向 URI 应为 http://localhost,在启用了公共客户端流的移动和桌面应用程序平台中:

enter image description here

当我运行下面的示例代码并使用管理员帐户登录时,我成功收到包含用户许可证信息的响应,如下所示:

import asyncio
from azure.identity import InteractiveBrowserCredential
from msgraph import GraphServiceClient

CLIENT_ID = 'appID'
TENANT_ID = 'tenantID'
SCOPES = ['LicenseAssignment.ReadWrite.All']

credential = InteractiveBrowserCredential(
    client_id=CLIENT_ID,
    tenant_id=TENANT_ID
)

graph_client = GraphServiceClient(credential)

async def get_user_license_details(user_id):
    try:
        license_details_response = await graph_client.users.by_user_id(user_id).license_details.get()
        license_details = license_details_response.value

        if license_details:
            print(f"License details for user {user_id}:")
            for license in license_details:
                print(f"License SKU ID: {license.sku_id}")
                print(f"SKU Part Number: {license.sku_part_number}")

                if license.service_plans:
                    print("Assigned Service Plans:")
                    for plan in license.service_plans:
                        print(f"  Service Plan ID: {plan.service_plan_id}")
                        print(f"  Service Plan Name: {plan.service_plan_name}")
                        print(f"  Provisioning Status: {plan.provisioning_status}")
                        print(f"  Applies to: {plan.applies_to}")
                else:
                    print("No assigned service plans found.")
        else:
            print(f"No license details found for user {user_id}.")

    except Exception as e:
        print(f"Error retrieving license details: {e}")

async def main():
    user_id = 'userID'
    await get_user_license_details(user_id)

asyncio.run(main())

回复:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.