При разработке различных интеграций, например, корпоративных чат-ботов (Битрикс24, Telegram), часто возникает нетривиальная задача. Бот получает команду от сотрудника (например, «пришли счет 123») и должен определить, имеет ли этот конкретный сотрудник права на просмотр данного документа в 1С. Проблема заключается в том, что сеанс бота в 1С работает под своим служебным пользователем, а права (особенно ограничения на уровне записей — RLS) необходимо проверить для совершенно другого пользователя.
Давайте подробно разберем эту ситуацию, проанализируем ограничения платформы 1С и рассмотрим несколько эффективных способов решения данной задачи.
В первую очередь выясним причину, по которой нельзя просто использовать встроенные функции платформы. В 1С существуют методы проверки прав, такие как ПравоДоступа() или функции БСП вроде УправлениеДоступом.ЕстьПраво(). Однако они имеют свои ограничения:
ПравоДоступа("Чтение", Метаданные.ОбъектМетаданных) проверяет только базовые права на сам объект метаданных (справочник или документ в целом), а не на конкретную ссылку.Пользователи.РолиДоступны(), также не учитывают ограничения RLS (Record Level Security).Посмотрим на практические архитектурные решения, которые помогут нам обойти это ограничение.
Если ваша конфигурация построена на базе современной Библиотеки стандартных подсистем (БСП), механизмы RLS там оптимизированы через предварительный расчет прав. Вместо тяжелых вычислений «на лету», БСП хранит готовые разрешения в специальных регистрах. Сделаем допущение, что данные в регистрах актуальны, и проанализируем их.
Нам понадобятся два служебных регистра сведений:
РегистрСведений.КлючиДоступаКОбъектам — хранит идентификатор (ключ) доступа для конкретной ссылки (документа, справочника).РегистрСведений.ДоступныеКлючиДоступаПользователей — хранит список ключей, разрешенных конкретному пользователю или его группе доступа.Мы можем написать запрос, который свяжет эти таблицы. Если в результате запроса возвращается запись — у нужного пользователя есть доступ к конкретному документу. Это очень быстрый метод, не требующий создания новых сеансов.
Поскольку боту нужно получить стопроцентно точный результат работы RLS, самым архитектурно правильным решением будет запуск сеанса под проверяемым пользователем. Разберем по шагам, как это реализовать с помощью HTTP-сервисов.
BotIntegration).РАЗРЕШЕННЫЕ.Рассмотрим пример кода внутри обработчика HTTP-сервиса:
Функция ПолучитьДокумент(ЗапросHTTP)
НомерСчета = ЗапросHTTP.ПараметрыЗапроса.Получить("Номер");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| СчетНаОплату.Ссылка КАК Ссылка
|ИЗ
| Документ.СчетНаОплату КАК СчетНаОплату
|ГДЕ
| СчетНаОплату.Номер = &Номер";
Запрос.УстановитьПараметр("Номер", НомерСчета);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
// RLS отсек документ, либо такого номера не существует
Возврат ОтветитьБоту("Извините, документ не найден или у вас нет к нему доступа.");
Иначе
// Права есть, обрабатываем и возвращаем файл счета
Возврат СформироватьИОтправитьСчет();
КонецЕсли;
КонецФункции
Этот подход гарантирует абсолютно корректную отработку всех механизмов безопасности, так как код выполняется непосредственно в контексте нужного пользователя.
Если по каким-то причинам публикация HTTP-сервиса невозможна, рассмотрим альтернативный вариант — COM-соединение (через объект V83.COMConnector). Суть аналогична предыдущему методу:
В текущем служебном сеансе мы программно инициализируем подключение к этой же самой информационной базе, но в строке подключения передаем учетные данные целевого пользователя. Внутри созданного COM-объекта мы пытаемся найти нужный документ. Если он возвращается — права есть.
Важно: Этот метод дает точный результат RLS, но инициализация COM-соединения потребляет много ресурсов системы и занимает время. Для массовых или высоконагруженных ботов этот вариант следует использовать с большой осторожностью.
Чтобы не нагружать систему тяжелыми запросами к регистрам БСП или созданием новых сеансов (HTTP/COM), всегда стоит сначала проверять базовые права. Если у пользователя в принципе нет роли на чтение документов данного типа, проверять RLS бессмысленно.
Проанализируем, как проверить наличие ролей у пользователя без его авторизации. Для этого используем свойства объекта ПользователиИнформационнойБазы.
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("ИвановИИ");
Если ПользовательИБ <> Неопределено Тогда
// Проверяем наличие полных прав
Если ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава) Тогда
Сообщить("Это администратор, доступ разрешен ко всему.");
КонецЕсли;
// Проверяем наличие роли на чтение нужного документа
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ЧтениеСчетовНаОплату) Тогда
Сообщить("У пользователя нет даже базовых прав на чтение счетов.");
КонецЕсли;
КонецЕсли;
Только после успешного прохождения этой легковесной проверки имеет смысл переходить к ресурсоемким проверкам конкретной ссылки через HTTP-вызов или регистры БСП.
Мы рассмотрели несколько рабочих подходов к решению задачи проверки RLS для не текущего пользователя. Для максимальной стабильности и надежности в современных архитектурах рекомендуется использовать связку Предварительной проверки ролей и внутреннего HTTP-сервиса. Это обеспечит и безопасность, и полную совместимость с логикой работы платформы 1С.