При организации распределенной информационной базы (РИБ) разработчики нередко сталкиваются с ситуацией, когда регламентный или интерактивный обмен данными завершается аварийной остановкой с ошибкой нарушения прав доступа. Типичный сценарий: в конфигурацию добавлен специфический справочник (например, справочник паролей или персональных данных), доступ к которому строго ограничен отдельной ролью и убран из роли ПолныеПрава. В результате фоновое задание или пользователь без специализированных прав не могут прочитать входящее сообщение обмена.
Выясним причину такого поведения платформы 1С:Предприятие и рассмотрим практические способы решения этой проблемы.
Проанализируем механику работы распределенной информационной базы. При загрузке данных вызывается метод ПланыОбмена.ПрочитатьИзменения. Во время десериализации XML-пакета платформа выполняет непосредственную запись объектов в базу данных. При этом свойство ОбменДанными.Загрузка = Истина отключает выполнение прикладных проверок и событийных обработчиков в модулях объектов, однако оно не отменяет проверку прав доступа платформы.
Если у текущего пользователя информационной базы или у контекста, в котором выполняется фоновое задание, отсутствуют права на чтение, добавление или изменение входящего объекта, платформа прерывает транзакцию загрузки системной ошибкой прав доступа. Попытка установить привилегированный режим на стороне тонкого или толстого клиента также завершится неудачей, поскольку контекст клиента лишен этой возможности.
Разберем по шагам наиболее универсальный и правильный подход. Чтение данных из потока XML и вызов методов планов обмена необходимо полностью делегировать серверному контексту, включив привилегированный режим. В привилегированном режиме платформенная проверка ролей и ограничений доступа на уровне записей (RLS) отключается, что позволяет успешно загрузить любые зарегистрированные изменения.
Посмотрим на пример вызова процедуры загрузки в общем модуле с установленным признаком «Сервер»:
&НаСервере
Процедура ПрочитатьСообщениеОбменаНаСервере(УзелОбмена, ЧтениеXML)
УстановитьПривилегированныйРежим(Истина);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения);
ЧтениеСообщения.ЗакончитьЧтение();
КонецПроцедуры
Также эту операцию можно вынести в отдельный общий модуль, у которого в свойствах метаданных установлен флаг «Привилегированный». Любой код, выполняемый внутри такого модуля на сервере, по умолчанию работает с максимальными правами в обход ограничений текущего пользователя сеанса.
Если обмен выполняется в автоматическом режиме по расписанию, фоновое задание всегда стартует на стороне сервера. Однако если у регламентного задания не указан конкретный пользователь, оно может выполняться под системным пользователем по умолчанию, у которого нет роли СуперАдмин.
Рассмотрим порядок действий для настройки прав:
ПользовательОбменаРИБ).Исключение прав на объект из типовой роли ПолныеПрава является рискованной практикой, способной сломать стандартные механизмы БСП (Библиотеки стандартных подсистем), регламентные процедуры и планы обмена. Если цель состоит в том, чтобы обычные пользователи или рядовые администраторы не видели чужие секретные данные, задачу следует решать на уровне интерфейса и криптографии.
ХешированиеДанных (например, с алгоритмом SHA-256). Даже если пользователь прочитает данные справочника, восстановить исходный пароль будет невозможно.ПриОтправкеДанныхПодчиненному можно программно отменить выгрузку конкретного элемента:
Процедура ПриОтправкеДанныхПодчиненному(Элемент, ОтправкаЭлемента, Создание)
Если ТипЗнч(Элемент) = Тип("СправочникСсылка.ПаролиКассиров") Тогда
// Пропускаем отправку конфиденциального объекта в подчиненный узел
ОтправкаЭлемента = ОтправкаЭлементаДанных.Пропустить;
КонецЕсли;
КонецПроцедуры
Применяя вынос десериализации сообщений обмена в привилегированный серверный контекст совместно с правильным проектированием ролевой модели, можно полностью устранить ошибки доступа при синхронизации РИБ без снижения безопасности системы.