已创建邮箱订阅但未触发邮件事件,Graph订阅功能为何失效?
从你提供的代码和描述来看,订阅创建流程无异常且初始URL验证通过,说明基础配置是通的。结合原型正常、生产环境异常的差异,重点排查以下几个方向:
服务器时间同步与订阅有效期问题
你设置的ExpirationDateTime为当前UTC时间加4230分钟(Graph订阅最大允许时长),但如果生产服务器系统时间与UTC存在偏差(时区配置错误、时间不同步),会导致实际过期时间提前,甚至订阅刚创建就失效。建议先检查服务器时间,也可以临时将过期时间设为30分钟做测试,同时通过API查询已创建订阅的状态:var subscriptions = graphClient.Subscriptions.Request().GetAsync().Result; foreach (var sub in subscriptions) { Console.WriteLine($"订阅ID: {sub.Id}, 状态: {sub.Status}, 过期时间: {sub.ExpirationDateTime}"); }生产环境通知URL的POST请求可达性
初始验证是Graph发送的GET请求,而实际邮件通知是POST请求。生产环境可能存在防火墙、WAF、负载均衡规则拦截POST请求,或者通知URL的HTTPS证书不被Graph信任(比如使用自签名证书)。确保:- 通知URL使用标准HTTPS端口443
- 证书由公共CA颁发且处于有效期内
- 服务器允许来自Microsoft Graph IP范围的POST请求
资源路径与用户身份格式问题
你使用/users/{mailAccount}/mailFolders/inbox/messages作为资源路径,若mailAccount是邮箱地址,需确认生产环境中该邮箱对应的用户对象存在,且Graph客户端有权访问。如果生产环境使用Application权限,建议改用用户ID(GUID)代替邮箱地址,避免邮箱别名、大小写等问题导致资源路径匹配失败。权限范围与租户邮件规则差异
若原型用的是Delegated权限(用户授权),而生产用的是Application权限(后台服务),需确认Azure AD中已授予Mail.ReadBasic.All或Mail.Read的管理员同意,且权限覆盖目标邮箱。另外,租户可能存在邮件流规则,将新邮件自动移动到归档、垃圾邮件等其他文件夹,这种情况下订阅的inbox不会触发通知,需检查邮件实际存放位置。订阅状态异常排查
即使创建时无异常,若通知URL多次返回错误(如5xx、4xx),Graph会自动取消订阅。可以查看Azure AD审核日志,或通过Graph API查询订阅状态,确认是否被标记为revoked或expired。
内容的提问来源于stack exchange,提问作者Holm76

