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

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

В практике разработки на платформе 1С:Предприятие часто возникает ситуация, когда недостаточно просто знать, что у пользователя есть право на чтение документов определенного типа. В современных конфигурациях активно используются механизмы RLS (Record Level Security) и БСП (Библиотека стандартных подсистем), которые могут ограничивать доступ к конкретным экземплярам документов, например, по организации, подразделению или складу. Если программа попытается обратиться к данным такого документа «в лоб», это приведет к ошибке прав доступа.

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

Различие между правами метаданных и правами на уровне записей

Прежде всего, проанализируем фундаментальное различие. Функция платформы ПравоДоступа("Чтение", Метаданные.Документы.РеализацияТоваровУслуг) проверяет только общие настройки в ролях пользователя. Если роль позволяет читать реализации, функция вернет Истина, даже если конкретная накладная по «чужой» организации скрыта от пользователя правилами RLS. Именно поэтому стандартная проверка метаданных часто оказывается бесполезной для решения задачи проверки прав на конкретный объект. Для наглядного анализа взаимосвязей ролей, профилей и ограничений RLS можно использовать обработку для анализа прав доступа.

Решение 1. Использование запроса с конструкцией ВЫБРАТЬ РАЗРЕШЕННЫЕ

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

Рассмотрим алгоритм реализации такой проверки:

  1. Создадим запрос к конкретной ссылке документа.
  2. Добавим ключевое слово РАЗРЕШЕННЫЕ.
  3. Если результат запроса пустой, значит, у пользователя нет прав на чтение этого документа.

Пример кода для реализации этого метода:


Функция ЕстьПравоНаЧтениеДокумента(СсылкаДокумента) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |   Реализация.Ссылка КАК Ссылка
        |ИЗ
        |   Документ.РеализацияТоваровУслуг КАК Реализация
        |ГДЕ
        |   Реализация.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаДокумента);
    
    РезультатЗапроса = Запрос.Выполнить();
    Возврат НЕ РезультатЗапроса.Пустой();
КонецФункции

Важный нюанс: этот метод проверяет именно право на чтение. Если документ найден запросом, мы можем быть уверены, что чтение полей объекта не вызовет ошибку «Объект не найден» или «Нарушение прав доступа».

Решение 2. Использование конструкции Попытка — Исключение

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

Проанализируем ситуацию, когда мы пытаемся считать реквизит документа, к которому нет доступа:


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

Однако стоит помнить, что исключение может возникнуть и по другим причинам (например, объект заблокирован другим пользователем). Поэтому данный метод лучше использовать для быстрой проверки «по месту», а не для сложной бизнес-логики. Для оперативной диагностики и выявления причин ошибок доступа у пользователей подойдёт помощник определения нарушений прав доступа.

Решение 3. Метод платформы ЗначениеРазрешено

Мало кто знает, что в платформе 1С существует встроенная функция ЗначениеРазрешено(). Она предназначена именно для проверки того, разрешен ли текущему пользователю доступ к конкретному значению (ссылке) с учетом всех действующих ограничений RLS.

Разберем пример её использования:


Если ЗначениеРазрешено(СсылкаНаДокумент) Тогда
    // Можно безопасно работать с объектом
Иначе
    // Доступ ограничен на уровне RLS
КонецЕсли;

Этот метод работает быстрее запроса и является наиболее «чистым» с точки зрения использования встроенного API платформы.

Решение 4. Использование функций БСП (Библиотека стандартных подсистем)

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

Для проверки прав на объект используйте следующий код:


// Проверка права на чтение конкретной ссылки
ПравоНаЧтение = УправлениеДоступом.ДоступноЧтениеОбъекта(СсылкаДокумента);

// Проверка права на изменение (запись) объекта
ПравоНаИзменение = УправлениеДоступом.ДоступноИзменениеОбъекта(СсылкаДокумента);

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

Решение 5. Работа в привилегированном режиме

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

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

  1. Выполним поиск документа в привилегированном модуле или используя УстановитьПривилегированныйРежим(Истина). Это позволит найти ссылку, игнорируя RLS.
  2. После того как ссылка найдена, проверим права текущего пользователя на эту ссылку одним из методов, описанных выше (например, через ЗначениеРазрешено).
  3. Если документ существует, но прав на него нет — выдаем осмысленное предупреждение пользователю, вместо того чтобы пытаться создать новый документ с тем же номером.

Пример реализации поиска с проверкой:


// В привилегированном модуле
Функция НайтиДокументБезУчетаПрав(Номер, Дата) Экспорт
    Возврат Документы.РеализацияТоваровУслуг.НайтиПоНомеру(Номер, Дата);
КонецФункции

// В основном коде
Ссылка = ОбщийМодульПривилегированный.НайтиДокументБезУчетаПрав(ДанныеИзФайла.Номер, ДанныеИзФайла.Дата);

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

Резюме

Для надежной проверки прав на документ программным способом:

← На главную