Доступ к почтовому ящику имперсонифицированного пользователя в Exchange Online

В предыдущих статьях (см. перечень в Использование EWS managed API v.2.0) была зарегистрирована учетная запись в Office 365 для компании Example Company и настроена имперсонификация пользователей. В данной заметке рассмотрим код программы на C#, которая с помощью EWS подключается к Exchange Online под пользователем Mail Admin и выполняет манипуляции с почтовыми ящиками других пользователей. Напомним, что пользователь Mail Admin имеет право импресонифицировать пользователей First User и Second User.

Для работы программы требуется, чтобы EWS 2.0 был проинсталлирован на компьютере. Кроме того, пароль Qwerty123 нужно заменить на настоящий.

В методе CreateService создается объект ExchangeService для подключения под указанным пользователем. Поскольку используется автоопределение реального адреса сервиса, который отличается для различных датацентров, требуется определить метод RedirectionUrlValidationCallback, где анализируется предполагаемый адрес переадресации, после чего разрешается или запрещается переадресация. Домен можно не указывать либо использовать ExampleCompany.onmicrosoft.com. Затем для каждого зарегистрированного в домене пользователя вызывается метод имперсонификации SetImpersonatedUser и выполняется доступ к почтовому ящику.

В следующем методе, PageThroughEntireInbox, перебираются сообщения из почтового ящика пользователя, загружается их содержимое и основные свойства, и в консоль выводится описание писем. Предварительно было отправлено несколько тестовых писем в текстовом и HTML формате.

#region

using System;
using System.Linq;
using System.Net;
using Microsoft.Exchange.WebServices.Autodiscover;
using Microsoft.Exchange.WebServices.Data;

#endregion

namespace Office365Impersonation
{
  internal static class Program
  {
    static void Main(string[] args)
    {
      // создать сервис
      var service = CreateService(
        @"Mail.Admin@ExampleCompany.onmicrosoft.com",
        "Qwerty123",
        null,
        @"Mail.Admin@ExampleCompany.onmicrosoft.com");

      var users = new[]
        {
          "First.User@ExampleCompany.onmicrosoft.com",
          "Second.User@ExampleCompany.onmicrosoft.com",
          "Third.User@ExampleCompany.onmicrosoft.com",
          "Fourth.User@ExampleCompany.onmicrosoft.com",
          "Mail.Admin@ExampleCompany.onmicrosoft.com"
        };

      // перебрать ящики пользователей
      foreach (var user in users)
      {
        Console.WriteLine("{1}*** Testing user '{0}' ***{1}{1}", user, Environment.NewLine);
        SetImpersonatedUser(service, user);
        // перебрать почтовые сообщения
        PageThroughEntireInbox(service);
      }
      Console.ReadKey();
    }

    static ExchangeService CreateService(
      string userName,
      string password,
      string domain,
      string autodiscoverAddress)
    {
      // подключение к Exchange сервису
      var service = new ExchangeService(ExchangeVersion.Exchange2013)
        {
          Credentials = new NetworkCredential(
            userName,
            password,
            domain)
        };

      const string autodiscoverUrl =
        @"https://outlook.office365.com/EWS/Exchange.asmx";
      try
      {
        service.AutodiscoverUrl(
          autodiscoverAddress,
          RedirectionUrlValidationCallback);
      }
      catch (AutodiscoverRemoteException ex)
      {
        Console.WriteLine("Exception is thrown: " + ex.Error.Message);
        service.Url = new Uri(autodiscoverUrl);
      }
      catch (AutodiscoverLocalException ex)
      {
        Console.WriteLine("Exception is thrown: " + ex.Message);
        service.Url = new Uri(autodiscoverUrl);
      }
      Console.WriteLine(service.Url);
      return service;
    }

    static bool RedirectionUrlValidationCallback(String redirectionUrl)
    {
      // допускаем все переадресации
      return true;
    }

    static void SetImpersonatedUser(
      ExchangeService service,
      string userAddress)
    {
      if (service == null || string.IsNullOrWhiteSpace(userAddress))
        return;
      userAddress = userAddress.Trim(' ', 't', ',', ';', '.');
      service.ImpersonatedUserId = new ImpersonatedUserId(
        (userAddress.IndexOf('@') > 0) ?
          ConnectingIdType.SmtpAddress :
          ConnectingIdType.PrincipalName,
        userAddress);
    }

    static void PageThroughEntireInbox(ExchangeService service)
    {
      var view = new ItemView(50);
      try
      {
        FindItemsResults findResults;
        do
        {
          findResults = service.FindItems(WellKnownFolderName.Inbox, view);

          var current = 0;
          foreach (var item in findResults.Items)
          {
            var message = item as EmailMessage;
            if (message == null)
              continue;

            // загрузка свойств письма
            message.Load(new PropertySet(
              BasePropertySet.FirstClassProperties));
            // информационная строка с описанием письма
            Console.WriteLine("Email #{1}{0}Subject:{2}{0}From:t{3}{0}To:t{4}{0}Send:t{5}{0}Get:t{6}{0}Body ({7}):{0}{8}",
                      Environment.NewLine,
                      ++current,
                      message.Subject,
                      message.From,
                      String.Join(
                        String.Format("{0}t", Environment.NewLine),
                        message.ToRecipients.Select(
                          address => address.ToString())),
                      message.DateTimeSent.ToShortDateString() + " " +
                      message.DateTimeSent.ToShortTimeString(),
                      message.DateTimeReceived.ToShortDateString() + " " +
                      message.DateTimeReceived.ToShortTimeString(),
                      message.Body.BodyType,
                      message.Body.Text);
          }
          view.Offset += 50;
        } while (findResults.MoreAvailable);
      }
      catch (ServiceResponseException ex)
      {
        Console.WriteLine("Exception is thrown: " + ex.Message);
      }
    }
  }
}

Приложение выводит следующую информацию:

https://outlook.office365.com/EWS/Exchange.asmx

*** Testing user 'First.User@ExampleCompany.onmicrosoft.com' ***

Email #1
Subject: The plain text test e-mail
From:   Illya Reznykov <SMTP:ireznykov@hotmail.com>
To:     First User <SMTP:First.User@ExampleCompany.onmicrosoft.com>
Send:   11.01.2014 12:48
Get:    11.01.2014 12:50
Body (Text):
Hi User,

This is a plain text message, and sent in order to test EWS access to user's
mailbox.

Sincerely,
Illya Reznykov




Email #2
Subject: The test e-mail
From:   Owner Account <SMTP:Owner.Account@ExampleCompany.onmicrosoft.com>
To:     First User <SMTP:First.User@ExampleCompany.onmicrosoft.com>
        Second User <SMTP:Second.User@ExampleCompany.onmicrosoft.com>
        Third User <SMTP:Third.User@ExampleCompany.onmicrosoft.com>
        Fourth User <SMTP:Fourth.User@ExampleCompany.onmicrosoft.com>
        Mail Admin <SMTP:Mail.Admin@ExampleCompany.onmicrosoft.com>
Send:   11.01.2014 12:20
Get:    11.01.2014 12:20
Body (HTML):
<html tabindex="-1" style="-ms-scrollbar-base-color: rgb(0, 0, 0); -ms-scrollbar-face-color: rgb(240, 240, 240); -ms-scrollbar-3dlight-color: rgb(227, 227, 227); -ms-scrollbar-shadow-color: rgb(160, 160, 160); -ms-scrollbar-highlight-color: rgb(255, 255, 255); -ms-scrollbar-darkshadow-color: rgb(105, 105, 105); -ms-scrollbar-arrow-color: rgb(0, 0, 0);">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=10">
<meta name="GENERATOR" content="MSHTML 11.00.9600.16428">
<style id="owaParaStyle" style="display: none;"><!--P {margin-top:0;margin-bottom:0;}--></style>
</head>
<body tabindex="0" style="" dir="ltr" aria-label="Message body" fPStyle="1">
<div name="divtagdefaultwrapper" id="divtagdefaultwrapper" style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000; margin: 0">
<p>Hi all,</p>
<p> </p>
<p>This message is used for testing EWS access to user's mailbox.</p>
<p> </p>
<p>Regards,</p>
<p>Owner Account</p>
<p> </p>
</div>
</body>
</html>


*** Testing user 'Second.User@ExampleCompany.onmicrosoft.com' ***

Email #1
Subject: The plain text test e-mail
From:   Illya Reznykov <SMTP:ireznykov@hotmail.com>
To:     Second User <SMTP:Second.User@ExampleCompany.onmicrosoft.com>
Send:   11.01.2014 12:49
Get:    11.01.2014 12:51
Body (Text):
Hi User,

This is a plain text message, and sent in order to test EWS access to user's
mailbox.

Sincerely,
Illya Reznykov




Email #2
Subject: The test e-mail
From:   Owner Account <SMTP:Owner.Account@ExampleCompany.onmicrosoft.com>
To:     First User <SMTP:First.User@ExampleCompany.onmicrosoft.com>
        Second User <SMTP:Second.User@ExampleCompany.onmicrosoft.com>
        Third User <SMTP:Third.User@ExampleCompany.onmicrosoft.com>
        Fourth User <SMTP:Fourth.User@ExampleCompany.onmicrosoft.com>
        Mail Admin <SMTP:Mail.Admin@ExampleCompany.onmicrosoft.com>
Send:   11.01.2014 12:20
Get:    11.01.2014 12:20
Body (HTML):
<html tabindex="-1" style="-ms-scrollbar-base-color: rgb(0, 0, 0); -ms-scrollbar-face-color: rgb(240, 240, 240); -ms-scrollbar-3dlight-color: rgb(227, 227, 227); -ms-scrollbar-shadow-color: rgb(160, 160, 160); -ms-scrollbar-highlight-color: rgb(255, 255, 255); -ms-scrollbar-darkshadow-color: rgb(105, 105, 105); -ms-scrollbar-arrow-color: rgb(0, 0, 0);">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=10">
<meta name="GENERATOR" content="MSHTML 11.00.9600.16428">
<style id="owaParaStyle" style="display: none;"><!--P {margin-top:0;margin-bottom:0;}--></style>
</head>
<body tabindex="0" style="" dir="ltr" aria-label="Message body" fPStyle="1">
<div name="divtagdefaultwrapper" id="divtagdefaultwrapper" style="font-family: Calibri,Arial,Helvetica,sans-serif; font-size: 12pt; color: #000000; margin: 0">
<p>Hi all,</p>
<p> </p>
<p>This message is used for testing EWS access to user's mailbox.</p>
<p> </p>
<p>Regards,</p>
<p>Owner Account</p>
<p> </p>
</div>
</body>
</html>


*** Testing user 'Third.User@ExampleCompany.onmicrosoft.com' ***

Exception is thrown: The account does not have permission to impersonate the requested user.

*** Testing user 'Fourth.User@ExampleCompany.onmicrosoft.com' ***

Exception is thrown: The account does not have permission to impersonate the requested user.

*** Testing user 'Mail.Admin@ExampleCompany.onmicrosoft.com' ***

Exception is thrown: The account does not have permission to impersonate the requested user.

Из результатов видно, что пользователь Mail Admin получил доступ только к почтовым ящикам пользователей First User и Second User. Кроме того, по умолчанию пользователь не может имперсонифицировать сам себя — доступ к почтовому ящику Mail Admin завершился исключением.


  1. Все используемые IP-адреса, имена серверов, компьютеров, доменов, пользователей, являются фиктивными и используются исключительно в демонстрационных целях.
  2. Информация приводится «AS IS».
Pin It

6 thoughts on “Доступ к почтовому ящику имперсонифицированного пользователя в Exchange Online

      Добавить комментарий

      Ваш адрес email не будет опубликован. Обязательные поля помечены *

      Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.