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

Microsoft.Exchange.WebServices 2.2.1.0生成令牌后调用接口报403错误

问题描述

开发环境

  • Visual Studio 2022,.NET版本4.8
  • Microsoft.Exchange.WebServices版本2.2.1.0
  • Microsoft.Exchange.WebServices.Auth版本15.0.0.0
  • Microsoft.Identity.Client版本4.63.0.0

Azure权限配置

Azure权限配置

问题详情

代码已成功生成令牌,但执行以下代码行时抛出403禁止错误:

var folders = _service.FindFolders(WellKnownFolderName.Inbox, new FolderView(10));

错误信息:

Microsoft.Exchange.WebServices.Data.ServiceRequestException: 'The request failed. The remote server returned an error: (403) Forbidden.'

完整代码

private static void ReadMailsFromExchangeServer()
{
    //  _service.Credentials = new WebCredentials("test@test.com", "qwerty", "tng");
    try
    {
        string token = GetAccessToken();

        ExchangeService _service = new ExchangeService(ExchangeVersion.Exchange2016)
        {
            Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
            Credentials = new OAuthCredentials(token),
        }; // Use your EWS endpoint

        // Impersonate the user you want to act on behalf of
        _service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "test@test.com");
        // Set X-AnchorMailbox header to the SMTP address of the mailbox being accessed
        _service.HttpHeaders.Add("X-AnchorMailbox", "test@test.com");//test@test.com
        _service.HttpHeaders.Add("X-PreferServerAffinity", "true");
        var folders = _service.FindFolders(WellKnownFolderName.Inbox, new FolderView(10));
        foreach (var folder in folders)
        {
            Console.WriteLine(folder.DisplayName);
        }
    }
    catch (Exception ex)
    {
    }
}

private static async void GetTokens()
{
    // Using Microsoft.Identity.Client 4.22.0
    var cca = ConfidentialClientApplicationBuilder
        .Create(ConfigurationManager.AppSettings["appId"])
        .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
        .WithTenantId(ConfigurationManager.AppSettings["tenantId"])
        .Build();

    var ewsScopes = new string[] { "https://outlook.office365.com/.default" };

    try
    {
        var authResult = await cca.AcquireTokenForClient(ewsScopes)
            .ExecuteAsync();
        var ewsClient = new ExchangeService();
        ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
        ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
        ewsClient.ImpersonatedUserId =
           new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "test@test.com");

        //Include x-anchormailbox header
        ewsClient.HttpHeaders.Add("X-AnchorMailbox", "test@test.com");
    }
    catch (Exception ex)
    {
    }
}

排查与解决建议

  1. 权限配置检查

    • 确认Azure应用已添加Exchange.ManageAsApp应用权限,并完成管理员同意。从权限配置图核对该权限是否存在,若缺失需补充后重新获取令牌。
    • 验证目标邮箱test@test.com的EWS访问是否启用:通过Exchange管理中心或PowerShell命令Get-CASMailbox test@test.com | Select-Object EwsEnabled查看,若结果为False,执行Set-CASMailbox test@test.com -EwsEnabled $true启用。
  2. 代码异步逻辑修正

    • 当前GetTokens为async void,调用时无法等待令牌生成完成,导致ReadMailsFromExchangeServer可能拿到无效令牌。重构令牌获取方法为异步返回:
      private static async Task<string> GetAccessToken()
      {
          var cca = ConfidentialClientApplicationBuilder
              .Create(ConfigurationManager.AppSettings["appId"])
              .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
              .WithTenantId(ConfigurationManager.AppSettings["tenantId"])
              .Build();
      
          var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
          var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
          return authResult.AccessToken;
      }
      
      同时修改邮件读取方法为异步:
      private static async Task ReadMailsFromExchangeServer()
      {
          try
          {
              string token = await GetAccessToken();
              // 后续服务初始化、文件夹查询逻辑保持不变
          }
          catch (Exception ex)
          {
              Console.WriteLine(ex.ToString()); // 不要吞异常,输出便于排查
          }
      }
      
  3. 令牌有效性验证

    • 解码生成的JWT令牌,检查roles声明中是否包含Exchange.ManageAsApp。若不存在,说明权限配置未生效,需重新配置权限并再次获取令牌。
  4. EWS版本适配

    • Office 365环境建议使用ExchangeVersion.ExchangeOnline(若当前EWS版本支持),替换代码中的ExchangeVersion.Exchange2016,避免版本不匹配引发的权限问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:13:18