如何通过Microsoft Graph API访问非登录用户的外部邮箱?
问题描述
我在Azure注册了应用,已获取User.Read和Mail.Read权限,想读取外部邮件账户的邮箱(不是登录用户自己的邮箱)。该外部邮箱已加入应用所属组的成员,请问怎么授权应用访问这个外部邮箱?是否可行?
我试过两种代码方案,但都失败:
- 使用
msgraph的用户名密码认证方式,调用graph_client.me.messages无结果; - 使用
msal的客户端凭证模式获取令牌,调用https://graph.microsoft.com/v1.0/users/{userId}/messages时返回ErrorAccessDenied错误:{'error': {'code': 'ErrorAccessDenied', 'message': 'Access is denied. Check credentials and try again.'}}
解决方案
一、可行性确认
可行,但需要调整权限类型和授权方式:
- 当前使用的委托权限(
User.Read/Mail.Read)仅能访问登录用户自身的邮箱,无法直接访问其他用户(包括外部账户)的邮箱; - 要访问其他用户邮箱,需使用应用权限,并配置对应邮箱访问权限。
二、具体配置步骤
添加应用权限
在Azure Portal的应用注册页面:- 进入「API权限」>「添加权限」>「Microsoft Graph」>「应用权限」;
- 添加
Mail.Read应用权限(注意区分委托权限); - 点击「授予管理员同意」(必须完成此步骤,否则权限无法生效)。
调整认证方式
不能再使用用户名密码的委托模式,需采用客户端凭证模式(对应你第二种msal的实现方式,但需修正权限和代码细节)。
三、代码修正
1. MSAL代码问题修正
- 请求URL语法错误:
$select前应使用?而非$,正确URL格式为:endpoint = f'https://graph.microsoft.com/v1.0/users/{userId}/messages?select=sender,subject' - 权限范围需改为应用权限格式:
['https://graph.microsoft.com/.default'](应用权限必须使用此格式)。
修正后的完整MSAL代码:
import requests import msal CLIENT_ID = "你的客户端ID" CLIENT_SECRET = "你的客户端密钥" AUTHORITY = "https://login.microsoftonline.com/你的租户ID" # 请勿使用common,填写实际租户ID USER_ID = "外部邮箱的用户ID或邮箱地址" SCOPE = ['https://graph.microsoft.com/.default'] app = msal.ConfidentialClientApplication( client_id=CLIENT_ID, client_credential=CLIENT_SECRET, authority=AUTHORITY ) result = app.acquire_token_silent(SCOPE, account=None) if not result: print("缓存中无合适令牌,从AAD获取新令牌") result = app.acquire_token_for_client(scopes=SCOPE) if "access_token" in result: # 修正URL语法错误 endpoint = f'https://graph.microsoft.com/v1.0/users/{USER_ID}/messages?select=sender,subject' r = requests.get( endpoint, headers={'Authorization': 'Bearer ' + result['access_token']} ) if r.ok: print('成功获取邮件') data = r.json() for email in data['value']: print(f"{email['subject']} ({email['sender']['emailAddress']['name']})") else: print(r.json()) else: print(f"获取令牌失败: {result.get('error_description')}")
2. 第一种方法失效原因
graph_client.me.messages中的me指代当前登录用户(代码中的adelev@contoso.com),因此只能读取该用户自身的邮箱,无法访问外部账户。即使使用委托模式,也需要登录用户拥有该外部邮箱的访问权限(如邮箱共享),但此类场景更适合使用应用权限实现。
四、额外注意事项
- 外部账户必须是Azure AD中的有效用户(你已将其加入组,满足该条件);
- 应用权限需要全局管理员授予同意,否则会提示权限不足;
- 确保用户ID或邮箱地址输入正确,避免拼写错误。
内容的提问来源于stack exchange,提问作者Renmy
相关产品推荐
相关产品推荐

