为 Microsoft Graph 向 Python 应用添加用户身份验证

在本文中,将用户身份验证添加到 使用 Microsoft Graph 生成 Python 应用中创建的应用程序。 然后,使用 Microsoft Graph 用户 API 获取经过身份验证的用户。

添加用户身份验证

适用于 Python 的 Azure 标识客户端库提供了许多TokenCredential实现 OAuth2 令牌流的类。 适用于 Python 的 Microsoft Graph SDK (预览版) 使用这些类对 Microsoft Graph 的调用进行身份验证。

配置 Graph 客户端以用于用户身份验证

首先, DeviceCodeCredential 使用 类通过 设备代码流请求访问令牌。

  1. 打开 graph.py ,并将其全部内容替换为以下代码。

    from configparser import SectionProxy
    from azure.identity import DeviceCodeCredential
    from msgraph import GraphServiceClient
    from msgraph.generated.users.item.user_item_request_builder import UserItemRequestBuilder
    from msgraph.generated.users.item.mail_folders.item.messages.messages_request_builder import (
        MessagesRequestBuilder)
    from msgraph.generated.users.item.send_mail.send_mail_post_request_body import (
        SendMailPostRequestBody)
    from msgraph.generated.models.message import Message
    from msgraph.generated.models.item_body import ItemBody
    from msgraph.generated.models.body_type import BodyType
    from msgraph.generated.models.recipient import Recipient
    from msgraph.generated.models.email_address import EmailAddress
    
    class Graph:
        settings: SectionProxy
        device_code_credential: DeviceCodeCredential
        user_client: GraphServiceClient
    
        def __init__(self, config: SectionProxy):
            self.settings = config
            client_id = self.settings['clientId']
            tenant_id = self.settings['tenantId']
            graph_scopes = self.settings['graphUserScopes'].split(' ')
    
            self.device_code_credential = DeviceCodeCredential(client_id, tenant_id = tenant_id)
            self.user_client = GraphServiceClient(self.device_code_credential, graph_scopes)
    

    此代码声明两个 DeviceCodeCredential 私有属性:对象和 GraphServiceClient 对象。 函数 __init__ 创建 的新实例 DeviceCodeCredential,然后使用该实例创建 的新 GraphServiceClient实例。 每次通过 user_client进行 API 调用以Microsoft Graph 时,都会使用提供的凭据来获取访问令牌。

  2. 将以下函数添加到 graph.py

    async def get_user_token(self):
        graph_scopes = self.settings['graphUserScopes']
        access_token = self.device_code_credential.get_token(graph_scopes)
        return access_token.token
    
  3. main.py 中的空display_access_token函数替换为以下内容。

    async def display_access_token(graph: Graph):
        token = await graph.get_user_token()
        print('User token:', token, '\n')
    
  4. 生成并运行应用。 当系统提示输入选项时,请输入 1 。 应用程序显示 URL 和设备代码。

    Python Graph Tutorial
    
    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    1
    To sign in, use a web browser to open the page https://microsoft.com/devicelogin and
    enter the code RB2RUD56D to authenticate.
    
  5. 打开浏览器并浏览到显示的 URL。 输入提供的代码并登录。

    重要

    请注意浏览到 https://microsoft.com/devicelogin时登录到浏览器的任何现有Microsoft 365 个帐户。 使用浏览器功能(如配置文件、来宾模式或专用模式)确保作为要用于测试的帐户进行身份验证。

  6. 完成后,返回到应用程序以查看访问令牌。

    提示

    出于验证和调试目的,只能) 使用 Microsoft 的联机令牌分析程序在 中https://jwt.ms解码工作或学校帐户的用户访问令牌 (。 如果在调用 Microsoft Graph 时遇到令牌错误,则分析令牌可能很有用。 例如,验证令牌中的声明是否 scp 包含预期的 Microsoft Graph 权限范围。

获取用户

配置身份验证后,可以进行第一个Microsoft图形 API调用。 添加代码以获取经过身份验证的用户的姓名和电子邮件地址。

  1. 将以下函数添加到 graph.py

    async def get_user(self):
        # Only request specific properties using $select
        query_params = UserItemRequestBuilder.UserItemRequestBuilderGetQueryParameters(
            select=['displayName', 'mail', 'userPrincipalName']
        )
    
        request_config = UserItemRequestBuilder.UserItemRequestBuilderGetRequestConfiguration(
            query_parameters=query_params
        )
    
        user = await self.user_client.me.get(request_configuration=request_config)
        return user
    
  2. main.py 中的空greet_user函数替换为以下内容。

    async def greet_user(graph: Graph):
        user = await graph.get_user()
        if user:
            print('Hello,', user.display_name)
            # For Work/school accounts, email is in mail property
            # Personal accounts, email is in userPrincipalName
            print('Email:', user.mail or user.user_principal_name, '\n')
    

如果现在运行应用,则登录后,应用将按名称欢迎你。

Hello, Megan Bowen!
Email: MeganB@contoso.com

代码说明

请考虑 函数中的 get_user 代码。 这只是几行,但有一些关键细节需要注意。

访问“me”

函数生成对 获取用户 API 的请求。 可通过两种方式访问此 API:

GET /me
GET /users/{user-id}

在这种情况下,代码将调用 GET /me API 终结点。 此终结点是在不知道其用户 ID 的情况下获取经过身份验证的用户的快捷方式。

注意

GET /me由于 API 终结点获取经过身份验证的用户,因此它仅适用于使用用户身份验证的应用。 仅限应用的身份验证应用无法访问此终结点。

请求特定属性

函数使用 $select 查询参数 来指定它所需的属性集。 Microsoft Graph 仅返回响应中请求的属性。 在 get_user中,使用 对象中的 MeRequestBuilderGetQueryParameters 参数完成select添加$select

后续步骤