Microsoft Graph API 读取未登录用户的电子邮件

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

我正在寻求帮助来解决我遇到的问题。我在 Azure 上注册了一个具有给定权限

User.Read
Mail.Read
的应用程序,并尝试按照不同的教程来读取用户电子邮件。

但是,我尝试访问的邮箱并不是教程中假设的登录用户的邮箱,而是外部邮件帐户。如何授予应用程序访问外部电子邮件邮箱的权限,而无需它是登录用户?这可能吗?外部电子邮件将作为应用程序在 Azure 中所属组的成员添加。

根据 Microsoft 的文档,我尝试使用它来阅读电子邮件

from msgraph import GraphServiceClient
from msgraph.generated.users.item.messages.messages_request_builder import MessagesRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration

scopes = ['User.Read']

# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'common'

# Values from app registration
client_id = 'YOUR_CLIENT_ID'

# User name and password
username = '[email protected]'
password = 'Password1!'

# azure.identity
credential = UsernamePasswordCredential(
    tenant_id=tenant_id,
    client_id=client_id,
    username=username,
    password=password)

graph_client = GraphServiceClient(credential, scopes)

query_params = MessagesRequestBuilder.MessagesRequestBuilderGetQueryParameters(
        select = ["sender","subject"],
)

request_configuration = RequestConfiguration(
query_parameters = query_params,
)

result = await graph_client.me.messages.get(request_configuration = request_configuration)

但我没有从中得到任何东西。我也尝试过使用

msal
和令牌

app = msal.ConfidentialClientApplication(
    client_id=CLIENT_ID,
    client_credential=CLIENT_SECRET,
    authority=AUTHORITY)

result = None

result = app.acquire_token_silent(SCOPE, account=None)
  
if not result:
    print("No suitable token exists in cache. Let's get a new one from Azure Active Directory.")
    result = app.acquire_token_for_client(scopes=SCOPE)


    if "access_token" in result:

        # userID taken from Azure
        endpoint = f'https://graph.microsoft.com/v1.0/users/{userId}/messages$select=sender,subject'
        r = requests.get(endpoint,
                        headers={'Authorization': 'Bearer ' + result['access_token']})
        if r.ok:
            print('Retrieved emails successfully')
            data = r.json()
            for email in data['value']:
                print(email['subject'] + ' (' + email['sender']
                    ['emailAddress']['name'] + ')')
         else:
             print(r.json())

这给了我:

 {'error': {'code': 'ErrorAccessDenied', 'message': 'Access is denied. Check credentials and try again.'}}.
python azure microsoft-graph-api
1个回答
0
投票

注意

Mail.Read
User.Read
API 权限仅允许您访问登录用户的邮件和详细信息,而不能访问其他用户。

如果访问令牌不包含执行操作所需的 API 权限,通常会出现错误 “ErrorAccessDenied”

因此要解决该错误,您需要向 Microsoft Entra ID 应用程序授予

Mail.ReadBasic.All
应用程序类型 API 权限:

enter image description here

现在生成访问令牌:

import msal
import requests

app = msal.ConfidentialClientApplication(
    client_id="ClientID",
    client_credential="Secret",
    authority="https://login.microsoftonline.com/TenantID"
)

# Acquire a token
result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])

if "access_token" in result:
    print("Access Token:")
    print(result['access_token'])
else:
    print("Error acquiring token:")
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))  

enter image description here

解码后的令牌:

enter image description here

现在使用以下查询来获取用户的消息:

https://graph.microsoft.com/v1.0/users/{userId}/messages$select=sender,subject

 if "access_token" in result:

        # userID taken from Azure
        endpoint = f'https://graph.microsoft.com/v1.0/users/{userId}/messages$select=sender,subject'
        r = requests.get(endpoint,
                        headers={'Authorization': 'Bearer ' + result['access_token']})
        if r.ok:
            print('Retrieved emails successfully')
            data = r.json()
            for email in data['value']:
                print(email['subject'] + ' (' + email['sender']
                    ['emailAddress']['name'] + ')')
         else:
             print(r.json())

由于我的环境没有许可证,所以无法获取邮件。 完成上述更改后,您将能够访问其他用户的邮件。*

参考:

获取消息-Microsoft Graph v1.0 |微软

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