EWS禁用后,如何用C#认证微软账户并读取Outlook指定邮件信息
使用Microsoft Graph API替代EWS实现需求
一、认证方式选择
控制台应用推荐使用设备码认证流,适配用户手动登录授权场景,支持多因素认证(MFA),完全规避EWS的认证限制问题。需依赖Microsoft.Identity.Client和Microsoft.Graph两个NuGet包。
二、核心实现步骤
1. 注册Azure AD应用
在Azure门户注册一个桌面类型应用,添加Mail.Read委托权限,记录生成的客户端ID(Client ID)。
2. 认证逻辑实现
通过设备码流获取Graph API访问令牌,完成用户身份验证。
3. 调用Graph API拉取邮件
指定需要的邮件字段,添加日期范围、数量限制等筛选条件,从收件箱获取目标数据。
三、完整代码示例
using Microsoft.Identity.Client; using Microsoft.Graph; using System; using System.Linq; using System.Threading.Tasks; namespace OutlookMailReader { class Program { // 替换为你的Azure AD应用客户端ID private static readonly string ClientId = "YOUR_CLIENT_ID"; private static readonly string[] Scopes = new[] { "Mail.Read" }; static async Task Main(string[] args) { // 初始化认证客户端 var publicClientApp = PublicClientApplicationBuilder .Create(ClientId) .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs) .WithRedirectUri("http://localhost") .Build(); // 获取访问令牌 AuthenticationResult authResult; try { var accounts = await publicClientApp.GetAccountsAsync(); authResult = await publicClientApp.AcquireTokenSilent(Scopes, accounts.FirstOrDefault()) .ExecuteAsync(); } catch (MsalUiRequiredException) { // 触发设备码登录流程 authResult = await publicClientApp.AcquireTokenWithDeviceCode(Scopes, deviceCodeResult => { Console.WriteLine(deviceCodeResult.Message); return Task.CompletedTask; }).ExecuteAsync(); } // 初始化Graph客户端 var graphClient = new GraphServiceClient( new DelegateAuthenticationProvider(requestMessage => { requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken); return Task.CompletedTask; })); // 构建筛选条件:过去24小时内的邮件,最多返回50封 var twentyFourHoursAgo = DateTime.UtcNow.AddHours(-24).ToString("o"); var messages = await graphClient.Me.MailFolders.Inbox.Messages .Request() .Select("UniqueBody,From,ConversationId,InternetMessageId,ReceivedDateTime,Subject,Body") .Filter($"ReceivedDateTime ge {twentyFourHoursAgo}") .Top(50) .GetAsync(); // 输出邮件数据 foreach (var message in messages) { Console.WriteLine($"主题: {message.Subject}"); Console.WriteLine($"发件人: {message.From?.EmailAddress?.Name} <{message.From?.EmailAddress?.Address}>"); Console.WriteLine($"接收时间: {message.ReceivedDateTime?.ToString("yyyy-MM-dd HH:mm:ss")}"); Console.WriteLine($"会话ID: {message.ConversationId}"); Console.WriteLine($"互联网消息ID: {message.InternetMessageId}"); Console.WriteLine($"唯一正文: {message.UniqueBody?.Content}"); Console.WriteLine($"完整正文: {message.Body?.Content}"); Console.WriteLine(new string('-', 50)); } } } }
四、关键说明
- 字段映射:你提到的
Unibody对应Graph API的UniqueBody字段,其余字段对应关系如下:from→FromConversaionId→ConversationIdInternetMessageId→InternetMessageIdDateTimeReceived→ReceivedDateTimesubject→Subjectbody→Body
- 筛选规则:
- 日期范围:使用
ReceivedDateTime ge {ISO时间戳},通过ToString("o")生成标准ISO 8601格式时间 - 数量限制:调用
Top(N)方法指定最多返回的邮件数量
- 日期范围:使用
- 权限要求:必须为Azure AD应用添加
Mail.Read委托权限,否则会触发权限不足的错误
内容的提问来源于stack exchange,提问作者Sunil Kumar
相关产品推荐
相关产品推荐

