Как запустить фоновое задание от имени другого пользователя в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда текущему пользователю не хватает прав на выполнение определенной технологической операции (например, проведение документов задним числом, прямая запись в защищенные регистры или выгрузка файлов в закрытые сетевые каталоги). Прямое расширение прав пользователя часто невозможно из соображений безопасности. В таких случаях возникает необходимость выполнить ресурсоемкую операцию в фоне, но под другой учетной записью, обладающей необходимыми привилегиями.

В этой статье мы подробно разберем, как решить эту задачу. Мы проанализируем как классические методы, предложенные участниками форума (использование регламентных заданий и COM-соединений), так и более современные, надежные и кроссплатформенные альтернативы, соответствующие стандартам разработки 1С.

Метод 1. Переход в привилегированный режим (Рекомендуемый стандарт)

Прежде чем приступать к сложным схемам с подменой учетных записей, давайте проанализируем первопричину. Зачем нам запускать задание от имени другого пользователя? Обычно это требуется только для обхода ограничений прав (RLS или обычных ролей). Платформа 1С предлагает встроенный и безопасный механизм для обхода ограничений прав доступа — Привилегированный режим.

Использование привилегированного режима позволяет временно отключить проверку прав доступа на уровне записей (RLS) и ролей для конкретного участка кода. Это гораздо безопаснее, чем передавать логин и пароль администратора в коде или создавать фиктивные сеансы.

Разберем, как применить этот режим на практике. Для этого мы можем включить свойство Привилегированный у общего модуля, в котором выполняется процедура фонового задания, либо использовать явную установку режима в коде:


Процедура ВыполнитьСлужебнуюОперациюНаСервере() Экспорт
    // Устанавливаем привилегированный режим
    УстановитьПривилегированныйРежим(Истина);
    
    // Код, выполняющий проведение документов или запись в регистры
    // Здесь ограничения прав текущего пользователя действовать не будут
    ДокументОбъект = Документы.РеализацияТоваровУслуг.НайтиПоРеквизиту("Номер", "00001").ПолучитьОбъект();
    Если ДокументОбъект <> Неопределено Тогда
        ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
    КонецЕсли;
    
    // Отключаем привилегированный режим
    УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры

Преимущества метода: Высокая скорость выполнения, полное соответствие стандартам безопасности 1С, отсутствие необходимости хранить чужие учетные данные.

---

Метод 2. Программное создание и запуск экземпляра регламентного задания

Если бизнес-логика требует, чтобы в истории изменений (например, в реквизитах "Автор" или "Ответственный") фигурировал именно конкретный служебный пользователь, можно использовать механизм регламентных заданий. Метод ФоновыеЗадания.Выполнить() всегда наследует текущего пользователя. Однако объект РегламентноеЗадание позволяет явно указать имя пользователя информационной базы, под которым должен выполняться код.

Рассмотрим по шагам, как программно создать, настроить и запустить регламентное задание "на лету":


// 1. Создаем экземпляр регламентного задания на основании предопределенного шаблона в метаданных
НовоеЗадание = РегламентныеЗадания.СоздатьРегламентноеЗадание("ВыгрузкаДанныхВБухгалтерию");

// 2. Указываем целевого пользователя, под которым должны выполняться действия
НовоеЗадание.ИмяПользователя = "СлужебныйПользовательДляИнтеграции";

// 3. Задаем параметры, которые будут переданы в процедуру-обработчик
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ПараметрПередачи1);
НовоеЗадание.Параметры = МассивПараметров;

// 4. Записываем регламентное задание в базу данных.
// Внимание: для записи у текущего пользователя должны быть права администратора!
НовоеЗадание.Записать();

// 5. Выполняем однократный запуск задания
НовоеЗадание.Выполнить();

// 6. При необходимости удаляем временное регламентное задание после завершения работы
НовоеЗадание.Удалить();

Нюансы использования: Если у созданного регламентного задания не заполнить свойство ИмяПользователя, платформа по умолчанию запустит его под служебным пользователем DefUser. Обратите внимание, что данный метод требует наличия административных прав у вызывающего пользователя для записи объектов типа РегламентноеЗадание.

---

Метод 3. Использование COM-соединения

Этот способ часто применяется в старых конфигурациях (например, сильно доработанных УТ 10.2 на обычных формах). Суть заключается в том, что мы программно создаем новое внешнее COM-соединение с текущей базой данных под целевым пользователем и запускаем нужную процедуру общего модуля внутри этого нового сеанса.

Посмотрим на пример реализации данного подхода:


// Инициализируем COM-соединитель
Connector = Новый COMОбъект("V83.COMConnector");

// Формируем строку подключения к текущей базе данных под целевым пользователем
СтрокаПодключения = "Srvr=""ИмяСервера"";Ref=""ИмяБазы"";Usr=""ЦелевойПользователь"";Pwd=""ПарольЦелевогоПользователя"";";

Попытка
    // Открываем новое соединение
    Соединение = Connector.Connect(СтрокаПодключения);
    
    // Вызываем экспортную процедуру общего модуля, которая выполнит работу под нужными правами
    Соединение.ИмяОбщегоМодуля.ВыполнитьДействие(Параметр1);
    
    Соединение = Неопределено;
Исключение
    ЗаписьЖурналаРегистрации("Ошибка COM-соединения", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;

Важное предупреждение: Несмотря на кажущуюся простоту, этот метод имеет серьезные технологические недостатки. Технология COM привязана к операционной системе Windows и не будет работать, если сервер 1С функционирует под управлением Linux. Кроме того, создание COM-соединения создает дополнительную нагрузку на сервер лицензирования, расходует клиентскую лицензию и выполняется сравнительно медленно.

---

Метод 4. Вызов через HTTP-сервисы (Современный и надежный способ)

Наиболее гибким, масштабируемым и кроссплатформенным решением в современных реалиях платформы 1С:Предприятие 8.3 является использование HTTP-сервисов. Этот подход полностью автономен, работает на любых операционных системах и не требует раздачи административных прав обычным пользователям.

Идея метода заключается в следующем: мы публикуем в нашей конфигурации простой HTTP-сервис. Из кода текущего пользователя мы отправляем HTTP-запрос к этому сервису, проходя авторизацию под учетной записью целевого пользователя. В обработчике запроса на стороне сервера запускается фоновое задание, которое автоматически наследует права авторизовавшегося пользователя.

Рассмотрим пример отправки запроса с клиента/сервера:


// Задаем параметры авторизации целевого пользователя
ИмяПользователя = "АдминистраторОбмена";
ПарольПользователя = "СеsecretPassword123";

// Создаем HTTP-соединение с авторизацией под целевым пользователем
Соединение = Новый HTTPСоединение("localhost", , ИмяПользователя, ПарольПользователя);

// Формируем запрос к нашему внутреннему HTTP-сервису
Запрос = Новый HTTPЗапрос("/ИмяПубликации/hs/TaskRunner/ExecuteTask");
Запрос.УстановитьТелоИзСтроки("ПараметрДляЗадания", КодировкаТекста.UTF8);

Попытка
    Ответ = Соединение.Получить(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        Сообщить("Задание успешно инициировано!");
    КонецЕсли;
Исключение
    ВызватьИсключение "Не удалось запустить фоновое задание через HTTP-сервис: " + ОписаниеОшибки();
КонецПопытки;

В модуле самого HTTP-сервиса (в обработчике метода GET/POST) мы принимаем запрос и запускаем фоновое задание. Поскольку этот код выполняется в контексте HTTP-сеанса пользователя "АдминистраторОбмена", запущенное фоновое задание получит все его права:


Функция ExecuteTaskПолучить(Запрос)
    // Читаем параметры из тела запроса
    Параметр = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    
    // Запускаем фоновое задание под правами текущего сеанса HTTP (под целевым пользователем)
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(Параметр);
    
    ФоновыеЗадания.Выполнить("ИмяОбщегоМодуля.ВыполнитьДействиеФоновогоЗадания", МассивПараметров);
    
    Возврат Новый HTTPСервисОтвет(200);
КонецФункции

Этот метод лишен недостатков COM-соединений: он работает мгновенно, не зависит от операционной системы и позволяет гибко управлять параметрами безопасности.

---

Резюме и рекомендации

Выбор оптимального метода зависит от архитектуры вашей системы и ограничений среды разработки:

  1. Используйте Привилегированный режим (Метод 1) в 90% случаев. Это самый простой, быстрый и безопасный способ выполнить действия в обход ограничений прав, не требующий управления чужими учетными данными.
  2. Используйте HTTP-сервисы (Метод 4), если вам критически важно запустить процесс именно в сеансе конкретного пользователя с его персональными настройками в кроссплатформенной среде.
  3. К программному созданию регламентных заданий (Метод 2) прибегайте только в случае, если у вызывающего пользователя гарантированно есть административные права для записи регламентных заданий.
  4. Избегайте использования COM-соединений (Метод 3) в новых разработках, так как эта технология устарела и не поддерживает кроссплатформенность на серверах Linux.
← На главную