Как работает авторизация и разделение данных в MS Exchange при использовании EWS в 1С

Программист IT и автоматизация бизнеса
← На главную

Интеграция 1С с Microsoft Exchange через Exchange Web Services (EWS) — это мощный инструмент для автоматизации работы с почтой, календарями и задачами. Однако разработчики часто сталкиваются с ситуацией, когда авторизация ведет себя непредсказуемо. Например, запрос к серверу может успешно выполняться даже при указании заведомо неверного пароля в коде. Разберем подробно, почему так происходит, как на самом деле работает проверка подлинности и как правильно организовать доступ к данным разных пользователей.

Почему EWS «проглатывает» неверный пароль: магия NTLM

При использовании COM-объекта MSXML2.XMLHTTP или WinHttp.WinHttpRequest.5.1 для отправки SOAP-запросов к Exchange, многие сталкиваются с тем, что параметры логина и пароля в методе open() игнорируются. Проанализируем причину этого поведения.

Большинство корпоративных серверов Exchange настроены на использование Windows Integrated Authentication (NTLM или Kerberos). Если компьютер, на котором запущена 1С, находится в том же домене, что и сервер Exchange, библиотека MSXML2.XMLHTTP может автоматически использовать учетные данные текущего сеанса Windows. Рассмотрим пошагово, что происходит:

  1. Объект 1С инициирует запрос к /EWS/Exchange.asmx.
  2. Сервер IIS (на котором работает Exchange) отвечает кодом 401 (Unauthorized) и сообщает, что поддерживает NTLM.
  3. Библиотека Windows, не спрашивая код 1С, автоматически подставляет токен текущего пользователя Windows.
  4. Сервер принимает этот токен, авторизует запрос и возвращает 200 OK.

В результате, какие бы учетные данные вы ни писали в методе open(), запрос выполняется от имени того, под кем запущен сеанс 1С или служба сервера 1С. Это объясняет, почему для «новых» доменных учеток всё работает «само», а для внешних или старых учеток авторизация может требовать явного указания пароля.

Пример базового запроса к EWS

Посмотрим на пример функции, которая создает объект для отправки запроса. Важно понимать, что метод open подготавливает соединение, но не гарантирует, что будут использованы именно эти Логин и Пароль, если включена сквозная авторизация.


Функция СоздатьXMLHTTP(ИмяСервера, Логин, Пароль)
    стрURL = "https://" + ИмяСервера + "/EWS/Exchange.asmx";
    oXMLHTTP = Новый COMОбъект("MSXML2.XMLHTTP");
    
    // Третий параметр "Ложь" означает синхронный запрос
    oXMLHTTP.open("POST", стрURL, Ложь, Логин, Пароль); 
    oXMLHTTP.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");    
    
    Возврат oXMLHTTP;
КонецФункции

Разделение данных: как получить доступ к конкретному ящику

Выясним, как Exchange понимает, чьи именно папки нужно вернуть. В EWS за это отвечает структура XML-запроса в теле SOAP-сообщения. Если мы используем стандартные константы, такие как msgfolderroot (корень почтового ящика) или inbox (входящие), сервер всегда возвращает данные того пользователя, под которым прошла авторизация.

Проанализируем пример SOAP-пакета для поиска папок:


| <m:ParentFolderIds>
|    <t:DistinguishedFolderId Id="msgfolderroot"/>
| </m:ParentFolderIds>

Если вы авторизованы как Иванов, вы увидите папки Иванова. Если как Петров — папки Петрова. Но как быть, если нам нужно одной сервисной учетной записью собирать почту со всех ящиков компании? Здесь на сцену выходит механизм Application Impersonation (Олицетворение).

Работа под «супер-учеткой»: Application Impersonation

Для массовой обработки писем без знания паролей каждого пользователя используется механизм «самозванства». Рассмотрим, как это реализовать:

  1. Настройка на стороне Exchange: Администратор должен назначить вашей сервисной учетной записи роль ApplicationImpersonation. Это делается через Exchange Management Shell командой New-ManagementRoleAssignment.
  2. Изменение XML-запроса: В заголовок SOAP-запроса (секция Header) необходимо добавить блок ExchangeImpersonation.

Разберем, как должен выглядеть заголовок в коде 1С, чтобы сервер понял, что мы хотим «прикинуться» другим пользователем:


Функция СформироватьЗаголовокИмперсонации(EmailЦелевогоПользователя)
    ТекстЗаголовка = 
    "<soap:Header>
    |  <t:ExchangeImpersonation>
    |    <t:ConnectingSID>
    |      <t:PrimarySmtpAddress>" + EmailЦелевогоПользователя + "</t:PrimarySmtpAddress>
    |    </t:ConnectingSID>
    |  </t:ExchangeImpersonation>
    |</soap:Header>";
    Возврат ТекстЗаголовка;
КонецФункции

Теперь, даже если ваша сессия авторизована под пользователем ServiceAccount, наличие этого заголовка заставит Exchange выполнять операции в контексте ящика EmailЦелевогоПользователя.

Особенности работы с Exchange 2013 и выше

При работе с Exchange 2013 стоит помнить о нескольких важных моментах:

Рекомендации по отладке и диагностике

Чтобы окончательно разобраться, под каким пользователем идет запрос и почему он проходит, рекомендуем использовать следующие инструменты:

  1. Fiddler: Установите его на стороне клиента 1С. Он перехватит HTTP-трафик и покажет вам реальные заголовки Authorization. Вы увидите, идет там NTLM, Negotiate или Basic.
  2. EWS Editor: Это официальная утилита от Microsoft (доступна на GitHub). Она позволяет вручную составить XML-запрос, проверить права имперсонации и увидеть структуру папок без написания кода в 1С. Это лучший способ проверить, есть ли у вашей учетки права на конкретный ящик.
  3. Логи IIS: На сервере Exchange в логах IIS можно увидеть статус-коды (например, 200 или 401) и имя пользователя, который прошел аутентификацию для каждого конкретного запроса к /EWS/Exchange.asmx.

Таким образом, для стабильной работы интеграции следует не полагаться на автоматическую авторизацию Windows, а четко настраивать права ApplicationImpersonation и явно управлять заголовками запроса. Это позволит вашей обработке 1С работать с любыми почтовыми ящиками централизованно и безопасно.

← На главную