msgraph-sdk-python无法返回用户数据问题求助
问题:获取Access Token正常但无法返回用户列表
按照微软官方教程实现Python应用权限调用Graph API,成功获取App-Only模式的Access Token,但执行列表用户操作时无结果返回,仅打印None。
main.py 文件
import asyncio import configparser from msgraph.generated.models.o_data_errors.o_data_error import ODataError from graph import Graph async def main(): print('Python Graph App-Only Tutorial\n') # Load settings config = configparser.ConfigParser() config.read(['config.cfg', 'config.dev.cfg']) azure_settings = config['azure'] graph: Graph = Graph(azure_settings) choice = -1 while choice != 0: print('Please choose one of the following options:') print('0. Exit') print('1. Display access token') print('2. List users') print('3. Me') try: choice = int(input()) except ValueError: choice = -1 try: if choice == 0: print('Goodbye...') elif choice == 1: await display_access_token(graph) elif choice == 2: await list_users(graph) elif choice == 3: await mee(graph) else: print('Invalid choice!\n') except ODataError as odata_error: print('Error:') if odata_error.error: print(odata_error.error.code, odata_error.error.message) async def display_access_token(graph: Graph): token = await graph.get_app_only_token() print('App-only token:', token, '\n') async def list_users(graph: Graph): users_page = await graph.get_users() print(users_page) # Output each users's details if users_page and users_page.value: for user in users_page.value: print('User:', user.display_name) print(' ID:', user.id) print(' Email:', user.mail) # If @odata.nextLink is present more_available = users_page.odata_next_link is not None print('\nMore users available?', more_available, '\n') async def mee(graph: Graph): user = await graph.me() async def make_graph_call(graph: Graph): # TODO return # Run main asyncio.run(main())
graph.py 文件
from configparser import SectionProxy from azure.identity.aio import ClientSecretCredential from kiota_authentication_azure.azure_identity_authentication_provider import ( AzureIdentityAuthenticationProvider ) from msgraph import GraphRequestAdapter, GraphServiceClient from msgraph.generated.users.users_request_builder import UsersRequestBuilder from kiota_abstractions.api_error import APIError import asyncio class Graph: settings: SectionProxy client_credential: ClientSecretCredential adapter: GraphRequestAdapter app_client: GraphServiceClient def __init__(self, config: SectionProxy): self.settings = config client_id = self.settings['clientId'] tenant_id = self.settings['tenantId'] client_secret = self.settings['clientSecret'] self.client_credential = ClientSecretCredential(tenant_id, client_id, client_secret) auth_provider = AzureIdentityAuthenticationProvider(self.client_credential) # type: ignore self.adapter = GraphRequestAdapter(auth_provider) self.app_client = GraphServiceClient(self.adapter) async def get_app_only_token(self): graph_scope = 'https://graph.microsoft.com/.default' access_token = await self.client_credential.get_token(graph_scope) return access_token.token async def get_users(self): try: query_params = UsersRequestBuilder.UsersRequestBuilderGetQueryParameters( # Only request specific properties select = ['displayName', 'id', 'mail'], # Get at most 25 results top = 25, # Sort by display name orderby= ['displayName'] ) request_config = UsersRequestBuilder.UsersRequestBuilderGetRequestConfiguration( query_parameters=query_params ) users = await self.app_client.users.get(request_configuration=request_config) return users except APIError as e: print(f'Error: {e.error.message}') async def me(self): try: me = await self.app_client.me.get() if me: print(me) except APIError as e: print(f'Error: {e}')
输出情况
选择选项2后,控制台仅输出None,无任何用户信息。
问题分析与解决方案
1. 核心问题:应用权限缺失
App-Only模式下调用/users接口需要User.Read.All(或更高权限)的应用权限,且必须完成管理员同意。如果未配置该权限,Graph API会返回权限不足错误,但当前代码未抛出该错误,导致返回None。
2. 修复步骤
步骤1:配置应用权限
- 登录Azure门户,进入Azure Active Directory → 应用注册,找到你的应用。
- 切换到API权限页面,点击添加权限 → 选择Microsoft Graph → 选择应用权限。
- 搜索并添加
User.Read.All权限,然后点击授予管理员同意(需要全局管理员权限)。
步骤2:修复错误处理逻辑
修改graph.py中的get_users方法,捕获错误后抛出,让上层代码处理:
async def get_users(self): try: query_params = UsersRequestBuilder.UsersRequestBuilderGetQueryParameters( select = ['displayName', 'id', 'mail'], top = 25, orderby= ['displayName'] ) request_config = UsersRequestBuilder.UsersRequestBuilderGetRequestConfiguration( query_parameters=query_params ) users = await self.app_client.users.get(request_configuration=request_config) return users except APIError as e: print(f'请求Graph API错误: {e.error.message}') raise # 抛出错误,让上层的ODataError捕获逻辑处理
步骤3:移除无效的/me调用
App-Only模式没有当前用户上下文,调用/me接口会报错,修改main.py中的mee函数:
async def mee(graph: Graph): print("App-Only模式下无法调用/me接口,请使用用户ID查询具体用户信息。")
内容的提问来源于stack exchange,提问作者royalsanga
相关产品推荐
相关产品推荐

