Как настроить выборку данных через OData в 1С:ERP при включенном ограничении прав доступа (RLS)?

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

При интеграции сторонних систем с 1С через стандартный интерфейс OData разработчики часто сталкиваются с ситуацией, когда включение ограничений доступа на уровне записей (RLS) полностью ломает получение данных. Например, в конфигурации 1С:ERP Управление предприятием при настройке профилей безопасности с ограничением хотя бы по одной организации стандартный OData-запрос к справочнику организаций или документам возвращает ошибку «Доступ. Отказ в доступе» (HTTP-код 401 или 403). Проанализируем причину такого поведения платформы и разберем способы получения разрешенных данных.

Выясним причину ошибки: почему OData не применяет поведение по умолчанию

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

Стандартный интерфейс OData платформы 1С:Предприятие работает точно так же: по умолчанию он формирует внутренний запрос без директивы чтения только разрешенных записей. В результате, обращаясь к коллекции объектов, интеграционный пользователь пытается прочитать всю таблицу целиком, натыкается на RLS-ограничение и получает ошибку отказа в доступе.

Основное решение: системный параметр allowedOnly=true

Для реализации поведения, аналогичного директиве ВЫБРАТЬ РАЗРЕШЕННЫЕ, в стандартном интерфейсе OData предусмотрен специальный параметр URL-запроса — allowedOnly=true. Добавив этот параметр к строке вызова, мы заставляем платформу выбирать только те данные, к которым у пользователя есть действующие права.

Посмотрим на пример формирования строки запроса:

http://server/base/odata/standard.odata/Catalog_Организации?$format=json&allowedOnly=true

При передаче allowedOnly=true платформа формирует внутренний запрос с отбором доступных записей, и ответ возвращает корректный список организаций без ошибки доступа.

Важные нюансы и ограничения параметра allowedOnly

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

  1. Работа только с коллекциями сущностей: Параметр allowedOnly=true действует исключительно при получении наборов данных (коллекций). Если внешняя система обращается к конкретной записи напрямую по ее уникальному идентификатору GUID (например, Catalog_Организации(guid'...')), и на эту запись у пользователя нет прав по RLS, параметр не спасет — платформа гарантированно вернет ошибку отказа в доступе.
  2. Связанные данные через $expand: Если в запросе используется раскрытие навигационных свойств через $expand, а внутри связанной таблицы оказывается объект, заблокированный правами доступа, запрос может завершиться ошибкой, даже несмотря на наличие флага allowedOnly=true.
  3. Влияние на производительность при пагинации: Использование allowedOnly=true совместно с постраничной навигацией (параметры $top, $skip) и подсчетом количества строк ($inlinecount или $count) создает высокую нагрузку на СУБД. Платформе приходится предварительно рассчитывать условия ограничений для всего массива записей, чтобы корректно определить смещение.

Специфика производительного режима RLS в 1С:ERP

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

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

Альтернативные архитектурные решения

Если штатный OData-интерфейс с параметром allowedOnly=true не закрывает потребности проекта из-за ограничений производительности или проблем со связанными сущностями, рассмотрим альтернативные варианты интеграции:

  1. Разработка собственного HTTP-сервиса:

    Создание собственного HTTP-сервиса в конфигурации или расширении позволяет гибко управлять логикой чтения. В коде обработчика запроса можно написать оптимальный текст запроса с ВЫБРАТЬ РАЗРЕШЕННЫЕ либо использовать привилегированный режим, отдавая внешнему клиенту сформированный JSON:

    
    УстановитьПривилегированныйРежим(Истина);
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |	Организации.Ссылка КАК Ссылка,
        |	Организации.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Организации КАК Организации";
    Результат = Запрос.Выполнить().Выгрузить();
    
  2. Выделенный сервисный пользователь без RLS:

    Для интеграционного обмена заводится отдельная учетная запись без ограничений по RLS (с полными правами только на чтение необходимых справочников и документов). Фильтрация данных по конкретной организации в этом случае переносится на сторону внешнего сервиса с помощью стандартного фильтра OData:

    ?$filter=Организация_Key eq guid'00000000-0000-0000-0000-000000000000'

    Такой подход полностью исключает накладные расходы механизмов RLS на стороне СУБД и предотвращает неожиданные отказы в доступе при выборке коллекций.

← На главную