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