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

Basic Authentication失效,如何更新代码读取Outlook收件箱邮件?

问题描述

有一个后台运行的遗留C#应用,负责将邮箱中的新邮件拉取至数据库,原代码如下:

ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
exchangeService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
                 
exchangeService.Credentials = new NetworkCredential("mail@domain.com","mailpassword", "");
PropertySet ItemPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
ItemPropertySet.RequestedBodyType = BodyType.Text;
ItemView itemView = new ItemView(10);
itemView.PropertySet = ItemPropertySet;

FindItemsResults<Item> Emails = exchangeService.FindItems(WellKnownFolderName.Inbox,
                    new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[]{
                    new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false)
                    }),
                    itemView);

近期执行FindItems方法时出现401未授权错误,错误详情如下:

11/10/2022 03:55:00 - ERROR WITH INBOUND EMAIL TASK TASK: The request failed. The remote server returned an error: (401) Unauthorized.
Microsoft.Exchange.WebServices
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Requests\ServiceRequestBase.cs:line 831
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& request) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Requests\ServiceRequestBase.cs:line 724
   at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Requests\MultiResponseServiceRequest.cs:line 157
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems[TItem](IEnumerable`1 parentFolderIds, SearchFilter searchFilter, String queryString, ViewBase view, Grouping groupBy, ServiceErrorHandling errorHandlingMode) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 832
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(FolderId parentFolderId, SearchFilter searchFilter, ViewBase view) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 937
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(WellKnownFolderName parentFolderName, SearchFilter searchFilter, ViewBase view) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 990

问题根源是Exchange Online已弃用Basic Authentication,需更新代码改用OAuth2认证恢复功能。

解决方案

1. 前置配置

  • 在Azure AD中注册应用程序,获取三个核心参数:客户端ID、客户端密钥、租户ID。
  • 为该应用添加Exchange Online的EWS.AccessAsUser.All应用权限,并完成管理员同意操作。

2. 代码修改

首先确保项目引用最新版本的Microsoft.Exchange.WebServices和Microsoft.Identity.Client NuGet包,之后替换认证逻辑:

using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;

// 替换为你的Azure AD配置参数
string clientId = "你的客户端ID";
string clientSecret = "你的客户端密钥";
string tenantId = "你的租户ID";
string mailboxAddress = "mail@domain.com";

// 升级Exchange版本到支持OAuth的版本
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2016);
exchangeService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
// 设置邮箱模拟(后台服务场景需配置此项)
exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxAddress);

// 获取OAuth2令牌
var confidentialClient = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clientSecret)
    .WithTenantId(tenantId)
    .Build();

var scopes = new[] { "https://outlook.office365.com/.default" };
var authResult = await confidentialClient.AcquireTokenForClient(scopes).ExecuteAsync();

// 设置OAuth凭据
exchangeService.Credentials = new OAuthCredentials(authResult.AccessToken);

// 原有邮件拉取逻辑保持不变
PropertySet ItemPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
ItemPropertySet.RequestedBodyType = BodyType.Text;
ItemView itemView = new ItemView(10);
itemView.PropertySet = ItemPropertySet;

FindItemsResults<Item> Emails = exchangeService.FindItems(WellKnownFolderName.Inbox,
    new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[]{
        new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false)
    }),
    itemView);

3. 关键注意事项

  • 版本升级:原代码使用的Exchange2007_SP1不支持OAuth,必须升级到Exchange2013及以上版本。
  • 权限类型:后台服务需使用应用权限,而非委托权限,避免用户交互依赖。
  • 令牌模式:使用客户端模式获取令牌,适配无界面的后台运行场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:15:21