Почему не срабатывает УстановитьПривилегированныйРежим(Истина) и как правильно повысить права в 1С?

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

Разработка механизмов разграничения прав доступа — одна из самых ответственных задач в 1С. Часто программисты сталкиваются с ситуацией, когда стандартному пользователю нужно дать возможность выполнить действие, на которое у него нет прав (например, прочитать список пользователей информационной базы или изменить защищенный регистр). Для этого в платформе предусмотрен метод УстановитьПривилегированныйРежим(Истина). Однако простое написание этой строки в коде не гарантирует результат. Рассмотрим подробнее, почему этот режим может «не срабатывать» и как правильно реализовать обход проверок прав доступа.

Разберем основную проблему: контекст выполнения

Главная ошибка, которую мы видим в примере автора темы, заключается в непонимании того, как долго действует привилегированный режим. Проанализируем ситуацию: разработчик вызывает УстановитьПривилегированныйРежим(Истина) в одной процедуре, а затем открывает форму обработки. Он ожидает, что права «повысятся» для всего сеанса или хотя бы для следующей процедуры.

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

Анализируем клиент-серверное взаимодействие

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

  1. На клиенте: Привилегированный режим в клиент-серверном варианте не работает. Платформа просто проигнорирует этот вызов, так как клиентская часть считается «недоверенной» средой. Если бы пользователь мог повысить себе права прямо в коде формы, это создало бы огромную дыру в безопасности.
  2. На сервере: Здесь режим работает в полную силу. Он позволяет игнорировать проверку прав (RLS) и выполнять действия, доступные только администратору.

Если вы работаете в обычном приложении (толстый клиент), ситуация может быть еще запутаннее. В файловом варианте базы привилегированный режим на клиенте может сработать, но как только база будет переведена на сервер (SQL), ваш код перестанет работать. Поэтому всегда ориентируйтесь на серверный контекст.

Почему ПользователиИнформационнойБазы требуют особого внимания?

В коде автора используется обращение к объекту ПользователиИнформационнойБазы. Рассмотрим пример кода, который вызывает ошибку:


// В модуле формы
Процедура ПриОткрытии()
    УстановитьПривилегированныйРежим(Истина);
    Попытка
        // Это обращение упадет с ошибкой, если у текущего пользователя нет административных прав
        СписокПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Исключение
        Сообщить("Недостаточно прав!");
    КонецПопытки;
КонецПроцедуры

Проанализируем ситуацию: даже если мы написали УстановитьПривилегированныйРежим(Истина), чтение списка пользователей ИБ — это операция, критичная для безопасности. В управляемых формах и современных версиях платформы прямой доступ к этим данным из модуля формы (даже на сервере формы) может быть ограничен. Правильным подходом будет вынос этой логики в общий модуль.

Решение №1: Использование привилегированного общего модуля

Это самый надежный и «чистый» способ решения проблемы. Создадим алгоритм действий:

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

Посмотрим на пример реализации в общем модуле:


// Общий модуль: РаботаСПользователямиПолныеПрава
// Свойства: Сервер = Истина, Привилегированный = Истина

Функция ПолучитьСписокИменПользователей() Экспорт
    // В привилегированном модуле режим включен ВСЕГДА по умолчанию
    МассивИмен = Новый Массив;
    СписокПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Для Каждого Пользователь Из СписокПользователей Цикл
        МассивИмен.Добавить(Пользователь.Имя);
    КонецЦикла;
    Возврат МассивИмен;
КонецФункции

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

Решение №2: Правильное использование метода в процедуре

Если вы все же решили использовать метод явно, разберем по шагам, как это сделать внутри процедуры. Посмотрите на исправленный вариант кода автора:


Процедура ПриОткрытии()
    // 1. Убеждаемся, что код выполняется там, где это разрешено (для обычных форм - это серверный вызов)
    // В обычном приложении для надежности лучше вызвать серверную функцию
    ПолучитьДанныеНаСервере();
КонецПроцедуры

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

Особенности внешних обработок

Важный момент, который стоит проанализировать — использование .epf файлов. Если вы запускаете внешнюю обработку через «Файл — Открыть», платформа накладывает жесткие ограничения в целях безопасности. В этом случае УстановитьПривилегированныйРежим(Истина) работать не будет. Это сделано для того, чтобы вредоносный код не мог получить доступ к данным в обход прав пользователя.

Чтобы обойти это ограничение, внешнюю обработку необходимо подключить к базе через механизм «Дополнительные отчеты и обработки» (в типовых конфигурациях на базе БСП). В этом случае код обработки будет выполняться в контексте конфигурации, и привилегированный режим станет доступен.

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

Подведем итоги нашего исследования. Если ваш код с УстановитьПривилегированныйРежим(Истина) не работает:

  1. Проверьте контекст: Вызов должен происходить на стороне сервера. В процедуре ПриОткрытии() на клиенте он бесполезен.
  2. Проверьте модуль: Лучшее место для такого кода — общий модуль с признаком «Привилегированный».
  3. Проверьте тип объекта: Если вы работаете с внешней обработкой, убедитесь, что она встроена в систему.
  4. Используйте диагностику: Всегда проверяйте результат функции ПривилегированныйРежим() в отладчике. Если она возвращает Ложь сразу после установки режима Истина, значит, текущий контекст выполнения запрещает повышение прав.

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

← На главную