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

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

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

Разбор синтаксических ошибок при вызове функции ПравоДоступа

Посмотрим на исходный пример, в котором разработчик попытался проверить право на бизнес-процесс:


Если ПравоДоступа("Чтение", БизнесПроцессы.Исполнение, &ТекущийПользователь,) ТОГДА
    ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = ?(ЗначениеЗаполнено(СтрокаДетальныеЗаписи.ДатаНачала),
        Формат(СтрокаДетальныеЗаписи.ДатаНачала, "ДФ=dd.MM.yyyy"),
        "Не определено");
КонецЕсли;

При попытке выполнить такой код платформа выдает ошибку синтаксического анализатора «Ожидается выражение». Выясним причину ее возникновения. В данном фрагменте допущены сразу три грубые ошибки:

  1. Символ амперсанда & в теле метода: амперсанд во встроенном языке 1С используется исключительно для обозначения директив компиляции (например, &НаСервере) либо внутри текста запросов для передачи параметров (например, &ТекущийПользователь). В коде модулей обращение к переменным или функциям через амперсанд недопустимо и вызывает ошибку компиляции.
  2. Лишняя запятая перед закрывающей скобкой: конструкция вида ,) воспринимается платформой как пропуск обязательного параметра следующего уровня, которого не существует в сигнатуре функции.
  3. Неверный второй параметр (менеджер вместо метаданных или ссылки): объект БизнесПроцессы.Исполнение является менеджером бизнес-процесса. Функция ПравоДоступа вторым параметром принимает либо объект метаданных (Метаданные.БизнесПроцессы.Исполнение), либо конкретную ссылку на объект информационной базы.

Корректный синтаксис функции ПравоДоступа

Проанализируем работу метода ПравоДоступа подробнее. Согласно синтакс-помощнику, метод имеет следующий синтаксис:

ПравоДоступа(<Право>, <Объект/Метаданные>, <Пользователь/Роль>, <СписокПараметров>)

Важные особенности использования параметров:

  1. Первый параметр: имя проверяемого права строкой (например, "Чтение", "Просмотр", "Добавление", "ИнтерактивноеДобавление").
  2. Второй параметр: объект описания метаданных (для проверки права на уровне всей таблицы) или ссылка на конкретный элемент (для проверки доступа с учетом ограничений RLS).
  3. Третий параметр (необязательный): указывает пользователя или роль, для которых выполняется проверка. Если третий параметр не указан, проверка всегда выполняется для текущего пользователя сеанса. Более того, явное указание третьего параметра требует наличия у текущего сеанса административных прав (права Администрирование), иначе платформа вызовет исключение нарушения прав доступа.

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


Если ПравоДоступа("Чтение", Метаданные.БизнесПроцессы.Исполнение) Тогда
    ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = "ЕСТЬ ДОСТУП";
Иначе
    ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = "НЕТ ДОСТУПА";
КонецЕсли;

Проверка прав на уровне конкретного объекта (RLS)

Если в базе настроено ограничение прав на уровне записей (RLS), права на всю таблицу у пользователя могут быть, но доступ к конкретному бизнес-процессу или задаче может быть закрыт. В этом случае проверка через Метаданные... вернет Истина, а чтение самого объекта приведет к ошибке.

Для проверки доступа к конкретной записи передадим в метод ссылку на эту запись:


Если ПравоДоступа("Чтение", СтрокаДетальныеЗаписи.БизнесПроцесс) Тогда
    // Заполняем область данными объекта
    ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = Формат(СтрокаДетальныеЗаписи.ДатаНачала, "ДФ=dd.MM.yyyy");
Иначе
    // Доступ ограничен на уровне записи
    ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = "";
КонецЕсли;

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

Оптимальное решение: фильтрация через запрос с ВЫБРАТЬ РАЗРЕШЕННЫЕ

Вместо того чтобы вручную проверять права для каждой строки выборки в коде, перенесем контроль прав непосредственно в запрос на выборку данных печатной формы. Конструкция ВЫБРАТЬ РАЗРЕШЕННЫЕ автоматически отсекает данные, на которые у пользователя нет прав по RLS.

Если исходная таблица соединяется через ЛЕВОЕ СОЕДИНЕНИЕ с таблицей бизнес-процессов или задач, то для недоступных пользователю записей все поля присоединенной таблицы вернут значение NULL. Посмотрим, как это обработать в коде:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |    втЗадачи.Ссылка КАК ЗадачаСсылка,
    |    втЗадачи.ДатаНачала КАК ДатаНачала
    |ИЗ
    |    втЗадачи КАК втЗадачи";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    Если Выборка.ЗадачаСсылка = NULL Тогда
        // У пользователя нет прав на чтение связанного объекта по RLS
        ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = "";
    Иначе
        // Доступ есть, анализируем заполненность даты
        Если ЗначениеЗаполнено(Выборка.ДатаНачала) Тогда
            ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = Формат(Выборка.ДатаНачала, "ДФ=dd.MM.yyyy");
        Иначе
            ОбластьОставшиесяЗадачиФИОДаты.Параметры.ДатаПлановая = "Не определено";
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Такой подход решает проблему производительности за счет выполнения единого запроса к базе данных и исключает необходимость ручного вызова функций проверки прав в цикле.

Проверка прав через Библиотеку стандартных подсистем (БСП)

В конфигурациях, использующих Библиотеку стандартных подсистем (например, «1С:Документооборот», «1С:ERP», «1С:Комплексная автоматизация»), для программной проверки прав рекомендуется использовать методы общего модуля УправлениеДоступом. Они корректно учитывают сложные механизмы политик доступа, рабочие группы и делегирование:


// Проверка права на объект метаданных
Если УправлениеДоступом.ЕстьПраво("Чтение", Метаданные.БизнесПроцессы.Исполнение) Тогда
    // Действия при наличии прав
КонецЕсли;

// Проверка права на конкретную ссылку
Если УправлениеДоступом.ЕстьПраво("Чтение", СтрокаДетальныеЗаписи.СсылкаНаОбъект) Тогда
    // Действия при наличии доступа к объекту
КонецЕсли;

Для массовой проверки списка ссылок в БСП предусмотрен метод УправлениеДоступом.ТаблицаПравДоступа, который позволяет проверить массив объектов за один пакетный вызов без лишней нагрузки на сервер.

← На главную