Почему возникает ошибка доступа "У пользователя недостаточно прав" в коде 1С, но не в консоли запросов?

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

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

Рассмотрим подробнее эту ситуацию, проанализируем причины такого расхождения в поведении платформы 1С и выясним причину возникновения ошибки ограничения прав доступа (RLS) на конкретных примерах из конфигураций 1С:ERP, 1С:УТ и 1С:Комплексная автоматизация.

Проанализируем ситуацию на примере

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

Посмотрим на пример типового кода, на котором происходит спотыкание:


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

    Запрос.УстановитьПараметр("Получатель", Получатель); 
    Запрос.УстановитьПараметр("Валюта", ?(ЗначениеЗаполнено(Валюта), Валюта, Неопределено)); 
    Выборка = Запрос.Выполнить().Выбрать(); 

    Если Выборка.Количество() = 1 И Выборка.Следующий() Тогда 
        БанковскийСчетПолучателя = Выборка.БанковскийСчетПолучателя; 
    Иначе 
        БанковскийСчетПолучателя = Справочники.БанковскиеСчетаКонтрагентов.ПустаяСсылка(); 
    КонецЕсли; 

    Возврат БанковскийСчетПолучателя; 
КонецФункции

Падение происходит на строке Запрос.Выполнить().Выбрать(). Разберем по шагам, почему в консоли этого не происходит, а в коде — происходит.

Почему поведение в консоли запросов и в коде отличается?

Кажется, что перед нами какая-то магия или "барабашка" в платформе, но этому есть вполне логичные технические объяснения. Выделим несколько основных причин:

  1. Передача значения Неопределено: Разные внешние консоли запросов по-разному работают с параметрами. В нашем запросе используется параметр &Валюта, который может принимать значение Неопределено. Некоторые консоли принудительно очищают этот параметр или передают его как пустую ссылку, из-за чего условие запроса меняется. Если в "правильной" консоли честно передать Неопределено, запрос также упадет с ошибкой прав, как и в коде.
  2. Ключевое слово РАЗРЕШЕННЫЕ: Зачастую в консолях разработчики по привычке ставят флаг "Выбирать разрешенные" (добавляет РАЗРЕШЕННЫЕ после слова ВЫБРАТЬ). При использовании этого слова система просто игнорирует записи, на которые у пользователя нет прав, и запрос завершается успешно, просто не выводя скрытые строки. В типовом коде, приведенном выше, слова РАЗРЕШЕННЫЕ нет, поэтому при попытке прочитать недоступную запись платформа генерирует исключение.
  3. Привилегированный режим: Некоторые консоли, запускаемые администраторами, могут неявно выполнять код в привилегированном режиме (например, используя УстановитьПривилегированныйРежим(Истина)). В этом режиме проверка прав RLS (Record Level Security) полностью отключается, и запрос отрабатывает без ошибок. В фоновом или клиентском коде под пользователем этот режим отключен.

Разберем влияние механизма RLS (Record Level Security)

Судя по тексту ошибки, права обрезаны механизмом ограничения доступа на уровне записей. В современных решениях, таких как 1С:ERP или 1С:УТ, используется производительный RLS. Доступ к справочнику БанковскиеСчетаКонтрагентов напрямую зависит от прав на владельца — справочники "Контрагенты" или "Партнеры".

Чтобы каждый раз при запросе не вычислять сложные иерархические права, система хранит предрассчитанные доступы в служебных регистрах сведений. Основной из них — регистр ИерархияПартнеров, а также регистр ключей доступа к объектам.

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

Инструкция по поиску и устранению проблемы

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

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

Таким образом, "барабашка" исчезает, когда мы понимаем, как работает производительный RLS в конфигурациях 1С и чем отличается контекст выполнения запроса в модуле от контекста его выполнения в сторонней консоли. Регулярная проверка актуальности служебных регистров прав избавит пользователей от подобных неожиданных ошибок.

← На главную