При интеграции 1С с корпоративными порталами и внешними системами часто используется архитектурная схема, при которой запросы отправляются к HTTP-сервисам 1С. Для упрощения администрирования в файле публикации default.vrd нередко прописывают единую учетную запись для авторизации в самой базе 1С, но при этом на веб-сервере (например, IIS) настраивают сквозную Windows-аутентификацию. Это позволяет системе определять, какой именно доменный пользователь совершает запрос.
Однако разработчики часто сталкиваются со следующей проблемой: при обращении разных доменных пользователей к HTTP-сервису в Журнале регистрации 1С системное поле ТекущийПользовательОС «залипает». В логах отображается один и тот же пользователь (тот, кто совершил самый первый запрос после перезапуска веб-сервера), хотя физически запросы отправляют совершенно разные сотрудники. Давайте подробно разберем, почему возникает это поведение и как правильно его устранить.
Данная проблема не является ошибкой платформы 1С. Это прямое следствие заложенной в систему оптимизации — работы механизма пула сеансов веб-сервисов и HTTP-сервисов. Давайте проанализируем по шагам, как ведет себя платформа 1С при обработке запросов через расширение веб-сервера (модули wsisapi.dll для IIS или mod_1c для Apache):
User1) отправляет запрос на веб-сервер, IIS авторизует его по протоколу NTLM/Kerberos. Поток веб-сервера начинает выполняться от имени этого пользователя (происходит имперсонация).default.vrd (например, usr=WebUser). Поскольку поток веб-сервера в этот момент имперсонирован под учетной записью User1, платформа считывает имя системного окружения и жестко записывает в параметры этого нового сеанса значение: ТекущийПользовательОС = "User1".УстановкаПараметровСеанса в модуле сеанса), платформа помещает этот сеанс в спящий пул повторного использования. По умолчанию для HTTP-сервисов параметр reuseSessions установлен в значение autouse.User2) совершает свой запрос. Веб-сервер успешно авторизует его как User2. Однако расширение веб-сервера 1С видит, что в пуле уже есть свободный готовый сеанс, созданный ранее под технической учетной записью WebUser. Чтобы ускорить отклик системы, платформа берет этот «спящий» сеанс из пула.User2, но внутри уже существующего сеанса, параметры которого были инициализированы под User1. Системные переменные окружения сеанса, включая ТекущийПользовательОС, при переиспользовании сеанса из пула не переинициализируются. В результате любые действия записываются в Журнал регистрации от имени User1.Разработчики часто пытаются решить эту проблему «в лоб» — изменяя параметры времени жизни сеанса и повторного использования в файле публикации default.vrd. Однако изменения нередко игнорируются системой по следующим причинам:
default.vrd могут не примениться сразу. Чтобы гарантированно применить настройки, необходимо выполнить полный сброс веб-сервера IIS через командную строку с помощью команды iisreset или перезапустить соответствующий пул приложений (Application Pool).<pool> с атрибутами size, maxAge) управляют TCP-соединениями между веб-сервером и кластером 1С. Они не отключают кэширование логических сеансов пользователей. За логические сеансы HTTP-сервисов отвечают атрибуты внутри тегов <httpServices> или конкретного <service>.0 (например, sessionMaxAge="0") на некоторых версиях платформы 1С воспринимается некорректно, из-за чего платформа сбрасывает настройки на значения по умолчанию. Для полного отключения повторного использования сеансов необходимо явно задавать директиву reuseSessions="dontuse".Рассмотрим подробнее два основных архитектурных решения этой проблемы, взвесив их преимущества и недостатки.
Если к вашему HTTP-сервису обращается большое количество пользователей (например, корпоративный портал на 5000 сотрудников), полное отключение пула сеансов приведет к катастрофическому падению производительности. На каждый микро-запрос серверу 1С придется заново запускать авторизацию и тяжелые обработчики инициализации сеанса.
В этой ситуации лучшим решением будет сохранить преимущества пула сеансов (высокая скорость работы), но передавать имя авторизованного на портале пользователя в HTTP-заголовках запроса.
Разберем реализацию этого метода по шагам:
Шаг 1. Настройка отправки заголовка на стороне внешней системы (портала)
При формировании HTTP-запроса на портале добавьте в заголовки авторизованного пользователя Windows. Например, добавьте кастомный заголовок: X-Current-OS-User: DOMAIN\ivanov_ii.
Шаг 2. Чтение заголовка и запись в Журнал регистрации в 1С
В коде метода вашего HTTP-сервиса в 1С считайте переданный заголовок и используйте его при записи событий в Журнал регистрации.
Посмотрим на пример реализации кода внутри метода HTTP-сервиса:
Функция ПолучитьДанныеКлиента(Запрос)
// Считываем имя доменного пользователя из нашего кастомного заголовка
ИмяПользователяОС = Запрос.Заголовки.Получить("X-Current-OS-User");
Если ИмяПользователяОС = Неопределено Тогда
// Если заголовок не передан, можем использовать резервные системные данные
ИмяПользователяОС = "Не определен (запрос без заголовка)";
КонецЕсли;
// Выполняем полезную работу сервиса
СтруктураДанных = ПолучитьСведенияИзБазы(Запрос);
// Формируем подробный комментарий для логов
КомментарийЛога = СтрШаблон("Пользователь ОС: %1 выполнил запрос к методу ПолучитьДанныеКлиента.", ИмяПользователяОС);
// Программная запись в Журнал регистрации вместо полагания на системные поля сеанса
ЗаписьЖурналаРегистрации(
"HTTP-сервис.ПолучитьДанныеКлиента",
УровеньЖурналаРегистрации.Информация,
,,,
КомментарийЛога
);
// Формируем ответ
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(ПреобразоватьВJSON(СтруктураДанных));
Возврат Ответ;
КонецФункции
Преимущества метода:
Если нагрузка на ваш HTTP-сервис невелика, а требования безопасности жестко предписывают использование системного логирования 1С (чтобы в колонке «Пользователь ОС» Журнала регистрации автоматически фигурировало реальное имя доменного пользователя), вы можете полностью отключить пул сеансов.
Рассмотрим, как правильно настроить файл публикации default.vrd:
Шаг 1. Редактирование файла default.vrd
Откройте файл default.vrd вашей публикации (обычно он находится в каталоге C:\inetpub\wwwroot\ИмяПубликации\ для IIS). Найдите секцию описания ваших HTTP-сервисов и добавьте атрибут reuseSessions="dontuse" для нужного сервиса:
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/MyDatabase"
ib="Srvr="Server1C";Ref="MyDatabase";">
<!-- Настройки общего пула соединений -->
<pool size="10" maxAge="1200" />
<!-- Настройки HTTP-сервисов -->
<httpServices publishByDefault="false">
<service name="MyExchangeService" enable="true" reuseSessions="dontuse" />
</httpServices>
</point>
Обратите внимание: значение reuseSessions="dontuse" указывает платформе при каждом входящем HTTP-запросе физически завершать предыдущий сеанс и инициировать абсолютно новый рабочий процесс с повторным чтением параметров операционной системы.
Шаг 2. Применение настроек на веб-сервере
После сохранения изменений в файле default.vrd обязательно сбросьте кэш веб-сервера. Для IIS выполните в командной строке от имени администратора:
iisreset
Для веб-сервера Apache перезапустите соответствующую службу (например, httpd или Apache2.4) через панель управления службами Windows или консоль Linux.
Недостатки метода:
Мы проанализировали причины «залипания» имени пользователя ОС при работе с HTTP-сервисами 1С. Для высоконагруженных систем наиболее правильным архитектурным решением является Решение 1 (передача имени пользователя через заголовки), так как оно сохраняет быстродействие веб-сервисов. К полному отключению пула сеансов (Решение 2) стоит прибегать только в редких случаях, когда частота запросов крайне мала, а системный контроль Журнала регистрации критически важен в первозданном виде.