You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 → From
    • ConversaionId → ConversationId
    • InternetMessageId → InternetMessageId
    • DateTimeReceived → ReceivedDateTime
    • subject → Subject
    • body → Body
  • 筛选规则:
    • 日期范围:使用ReceivedDateTime ge {ISO时间戳},通过ToString("o")生成标准ISO 8601格式时间
    • 数量限制:调用Top(N)方法指定最多返回的邮件数量
  • 权限要求:必须为Azure AD应用添加Mail.Read委托权限,否则会触发权限不足的错误

内容的提问来源于stack exchange,提问作者Sunil Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:25:35