我正在寻求帮助来解决我遇到的问题。我在 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.'}}.
注意:
和Mail.Read
API 权限仅允许您访问登录用户的邮件和详细信息,而不能访问其他用户。User.Read
如果访问令牌不包含执行操作所需的 API 权限,通常会出现错误 “ErrorAccessDenied”。
因此要解决该错误,您需要向 Microsoft Entra ID 应用程序授予
Mail.ReadBasic.All
应用程序类型 API 权限:
现在生成访问令牌:
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"))
解码后的令牌:
现在使用以下查询来获取用户的消息:
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())
由于我的环境没有许可证,所以无法获取邮件。 完成上述更改后,您将能够访问其他用户的邮件。*
参考: