Как разрешить проведение документа по регистру накопления, запретив его чтение пользователю в 1С?

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

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

В этой статье мы подробно проанализируем, почему стандартная опция «Привилегированное проведение» не всегда решает эту задачу (особенно в обычных формах и толстом клиенте), разберем внутренние механизмы платформы «1С:Предприятие» и предложим несколько надежных способов обхода этого ограничения.

В чем заключается сложность? Выясняем причину

На первый взгляд, задача кажется тривиальной. В свойствах документа на вкладке «Прочее» существует флаг «Привилегированное проведение при проведении» (или аналогичное свойство в модуле). Казалось бы, достаточно включить эту настройку, забрать у пользователя права на чтение регистра, и система сама запишет движения в привилегированном режиме. Однако на практике разработчики обычных форм сталкиваются с ошибкой Нарушение прав доступа!.

Это происходит из-за важной особенности платформы 1С:

Если проведение или отмена проведения документа выполняется на стороне клиента в клиент-серверном варианте (что является стандартом для Толстого клиента и Обычных форм), привилегированный режим на клиенте не устанавливается.

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

Рассмотрим подробнее три проверенных практических метода решения этой проблемы.

---

Решение 1. Настройка RLS с использованием условия «ГДЕ ЛОЖЬ»

Это наиболее элегантный и безопасный способ, не требующий изменения конфигурации или написания сложного программного кода. Мы обманем платформу, предоставив пользователю техническое право на чтение, но ограничив выдачу самих данных на уровне СУБД.

Разберем этот метод по шагам:

  1. Откройте необходимую роль пользователя в конфигураторе.
  2. Найдите проблемный регистр накопления.
  3. Установите флаги (галочки) напротив прав «Чтение» и «Изменение». Это обязательное условие, чтобы платформа могла беспрепятственно выполнять внутренние транзакции по записи и очистке движений.
  4. Перейдите на вкладку «Шаблоны ограничений» или сразу в ограничение доступа к данным (RLS) для права «Чтение».
  5. Для права «Чтение» добавьте строку ограничения со следующим текстом запроса: ГДЕ ЛОЖЬ Примечание: В некоторых версиях платформы также используют синтаксис ГДЕ 1 = 0 или ГДЕ ИСТИНА = ЛОЖЬ. Результат будет одинаковым.
  6. Для права «Изменение» ограничение RLS настраивать не нужно (оставьте поле пустым или напишите ГДЕ ИСТИНА).

Как это работает на практике: Обладая правом «Чтение», платформа успешно выполняет все транзакционные операции (включая очистку движений при отмене проведения документа). Однако при попытке прочитать данные через отчет, программный запрос или динамический список, СУБД накладывает условие ГДЕ ЛОЖЬ. В результате запрос всегда возвращает пустую выборку. Для пользователя данный регистр будет выглядеть абсолютно пустым, хотя движения в нем будут успешно создаваться при проведении документов.

---

Решение 2. Вынос очистки движений в серверный привилегированный модуль

Если по каким-то причинам вы не хотите использовать RLS (например, из-за возможного снижения производительности СУБД), нам придется прибегнуть к программному обходу через разделение контекста выполнения кода.

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

Выполним следующие действия:

  1. Создайте новый общий модуль (или используйте существующий) со следующими свойствами:
    • Клиент (обычное приложение) — выключено.
    • Сервер — включено.
    • Привилегированный — включено.
  2. Назовем этот модуль, например, ПроведениеСерверПривилегированный. Код внутри этого модуля выполняется без каких-либо проверок прав доступа и RLS текущего пользователя.
  3. Напишем в этом модуле экспортную процедуру для очистки движений регистра:
    
    Процедура ОчиститьДвиженияДокументаНаСервере(СсылкаНаДокумент, ИмяРегистра) Экспорт
                
        НаборЗаписей = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
                
        // Записываем пустой набор записей, тем самым очищая движения
        Попытка
            НаборЗаписей.Записать(Истина);
        Исключение
            ВызватьИсключение "Не удалось очистить движения по регистру " + ИмяРегистра + ". Ошибка: " + ОписаниеОшибки();
        КонецПопытки;
                
    КонецПроцедуры
    
  4. В модуле документа в обработчиках ОбработкаПроведения или ОбработкаУдаленияПроведения замените стандартные механизмы записи движений на вызов нашей новой процедуры.

Этот способ гарантирует, что запись физически произойдет на сервере под полными правами системы, минуя клиентские ограничения прав текущей сессии пользователя.

---

Решение 3. Обход встроенных проверок кода конфигурации (на примере УдалитьДвиженияРегистратора)

В старых типовых конфигурациях 1С (таких как Управление производственным предприятием 1.3 или Управление торговлей 10.3) при отмене проведения документов часто вызывается общая процедура ОбщегоНазначения.УдалитьДвиженияРегистратора().

Даже если вы настроили привилегированный режим, эта процедура может содержать встроенную программную проверку прав доступа следующего вида:


Если НЕ ПравоДоступа("Изменение", МетаданныеНабора) Тогда
    СообщитьОбОшибке("Нарушение прав доступа", Отказ, СтрокаДвижения.Имя);
    Возврат;
КонецЕсли;

Эта проверка выполняется в обычном режиме исполнения кода на клиенте и сразу вызывает исключение. Чтобы обойти эту проблему без изменения типового кода всей конфигурации, лучше всего использовать комбинацию Решения 1 (настройка RLS ГДЕ ЛОЖЬ). Так как формально у пользователя будет право «Изменение» на метаданные регистра, проверка ПравоДоступа вернет Истина, а реальные данные останутся защищенными.

---

Решение 4. Временное отключение RLS (для конфигураций на БСП)

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

Посмотрим на пример кода, который необходимо выполнять на сервере:


// Отключаем RLS для текущего сеанса
ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = Ложь;

Попытка
    // Выполняем запись движений или проведение документа
    ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
    
    // Обязательно возвращаем проверку RLS в исходное состояние
    ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = Истина;
Исключение
    // В случае ошибки критически важно вернуть RLS обратно в блоке Исключение!
    ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = Истина;
    ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

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

Резюме

Мы проанализировали специфику работы платформы «1С:Предприятие» при записи движений регистратора в условиях ограничений прав. Наиболее стабильным, не требующим программирования и рекомендуемым 1С методом для закрытия чтения регистров при сохранении возможности их изменения является использование механизма RLS с условием «ГДЕ ЛОЖЬ» на право чтения.

← На главную