Почему возникает ошибка «Недостаточно прав» при записи документа 1С, если в RLS настроены права на изменение?

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

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

В этой статье мы подробно разберем, почему так происходит, как работает механизм Record Level Security (RLS) «под капотом» и на что нужно обратить внимание, чтобы устранить подобные «затыки».

Механика работы RLS при изменении данных

Рассмотрим ситуацию, с которой столкнулся автор темы. Есть самописный документ, доступ к которому ограничен по статусам через RLS. Для ролей прописаны ограничения на «Чтение» и «Изменение». Пользователь пытается изменить документ, переводя его в новый статус, который вроде бы добавлен в список разрешенных, но получает отказ.

Проанализируем ключевой нюанс работы RLS на «Изменение». Платформа 1С выполняет проверку условий ограничения доступа дважды:

  1. Проверка «ДО» изменения: Система проверяет, имеет ли право пользователь модифицировать объект в его текущем состоянии (том, которое сейчас записано в базе данных).
  2. Проверка «ПОСЛЕ» изменения: Перед фиксацией транзакции система проверяет, будет ли объект соответствовать условиям RLS в его новом состоянии.

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

Почему одинаковые условия в «Чтении» и «Изменении» — это ловушка

Часто разработчики копируют текст ограничения из права «Чтение» в право «Изменение». Разберем, к чему это приводит. Допустим, условие выглядит так:


ГДЕ Статус = Значение(Перечисление.Статусы.Черновик)
   ИЛИ Статус = Значение(Перечисление.Статусы.НаСогласовании)

Если пользователь попытается перевести документ из статуса НаСогласовании в статус Утвержден, транзакция прервется. Несмотря на то что в момент нажатия кнопки «Записать» документ был доступен для редактирования (статус НаСогласовании), после записи он должен получить статус Утвержден, который отсутствует в условии.

Для решения этой проблемы логика права «Изменение» должна быть шире. Мы должны позволить пользователю записывать документ, если он был доступен ему хотя бы в момент начала операции. Однако на уровне чистого RLS в роли это реализовать сложно без разделения прав на статусы «откуда» и «куда».

Технические нюансы отладки: кэш и фоновые процессы

В процессе обсуждения автор упомянул, что код иногда «не обновляется» — изменения в модуле внесены, но отладчик их игнорирует. Выясним причины такого поведения:

  1. Динамическое обновление (Демон): Это главный враг стабильной разработки. При «демоническом» обновлении сервер 1С может продолжать исполнять старые версии скомпилированных модулей для существующих сеансов. Помогает только полное завершение всех сеансов и монопольное обновление конфигурации базы данных.
  2. Серверный кэш: В клиент-серверном варианте скомпилированные модули кэшируются процессом rphost. Если вы видите, что точка останова срабатывает на пустом месте или игнорирует измененные строки, необходимо почистить кэш сервера (каталог snacc) или перезапустить службу сервера 1С.
  3. Очистка локального кэша: Не забывайте про локальный кэш пользователя. Часто ошибка доступа может «залипнуть» в кэшированных параметрах сеанса, которые используются в условиях RLS.

Влияние связанных объектов: Табличные части и Регистры

Иногда ошибка «Недостаточно прав» при вызове ДокОбъект.Записать() не имеет отношения к самому документу. Проанализируем смежные области:

Права на реквизиты и табличные части

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

Движения по регистрам

При записи документа (особенно с режимом Записывать или Проводить) система пытается очистить или создать записи в регистрах сведений, накопления или бухгалтерии. Если у пользователя настроен RLS на сам документ, но при этом ограничены права на регистры, в которые этот документ делает движения, ошибка возникнет именно в момент ДокОбъект.Записать().

Посмотрим на пример кода в подписке на событие или в модуле документа:


Движения.ОстаткиТоваров.Записывать = Истина;
Набор = Движения.ОстаткиТоваров;
Набор.Записать();

Если у пользователя нет прав на изменение регистра ОстаткиТоваров, система выдаст ошибку прав. В Журнале регистрации это событие часто отражается как «Отказ в доступе» к метаданным регистра, а не самого документа.

Как эффективно искать причину ошибки

Рассмотрим алгоритм поиска «спрятанных» проверок прав:

  1. Журнал регистрации: Это первое, куда нужно заглянуть. Ищите события со статусом «Ошибка» и категорией «Доступ». Там часто указывается конкретный объект (например, какой-нибудь вспомогательный РегистрСведений.НастройкиДоступа), на который не хватило прав.
  2. Остановка по ошибке: В конфигураторе включите режим «Остановка по ошибке». Если ошибка происходит в коде 1С (а не глубоко в ядре СУБД при проверке RLS), отладчик укажет на строку. Если это Записать(), попробуйте зайти внутрь (F11), чтобы проверить ПередЗаписью и ПриЗаписи.
  3. Замер производительности: Если обычная отладка не помогает, включите замер производительности перед вызовом записи. В результате вы увидите список всех процедур, которые вызывались (включая подписки на события других модулей). Это поможет найти «скрытый» код, который может пытаться записать данные в запрещенные области.
  4. Привилегированный режим: Если бизнес-логика требует смены статуса на недоступный пользователю, рассмотрите возможность выполнения записи в привилегированном модуле или использования конструкции:
    
    УстановитьПривилегированныйРежим(Истина);
    Объект.Записать();
    УстановитьПривилегированныйРежим(Ложь);
    
    Это позволит обойти проверку RLS для конкретной операции.

Итоги

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

← На главную