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

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

В практической работе администраторов и разработчиков 1С часто возникает задача: необходимо проверить, имеет ли определенный пользователь доступ на чтение или изменение конкретного экземпляра документа (например, ЗаказПокупателя). Ситуация осложняется, если в системе настроен сложный, разветвленный механизм ограничения доступа на уровне записей (RLS — Record Level Security).

Обычный пользователь с полными правами должен иметь возможность выбрать в интерфейсе тестируемого сотрудника, указать целевой документ и мгновенно получить вердикт: разрешен доступ или нет. Разберем по шагам, как решить эту задачу красиво, надежно и с учетом особенностей различных версий платформы и конфигураций.

Почему стандартная функция ПравоДоступа() не подходит?

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

Для решения этой задачи мы рассмотрим три надежных архитектурных подхода, а также разберем, почему популярный на форумах способ с «подменой параметров сеанса» является опасным и нерабочим.

Способ №1: Использование программного интерфейса БСП (для современных конфигураций)

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

В общем модуле УправлениеДоступом функции проверки прав поддерживают необязательный параметр Пользователь. Мы можем использовать следующие функции:

  1. УправлениеДоступом.ЧтениеРазрешено(ОписаниеДанных, Пользователь) — проверяет, разрешено ли чтение конкретного объекта (ссылки на документ) для указанного пользователя информационной базы.
  2. УправлениеДоступом.ИзменениеРазрешено(ОписаниеДанных, Пользователь) — проверяет права на изменение конкретного объекта для указанного пользователя.

Рассмотрим пример кода для проверки прав:


// Определим проверяемый документ и пользователя
ДокументСсылка = Документы.ЗаказПокупателя.НайтиПоНомеру("000000001", ТекущаяДата());
ПроверяемыйПользователь = Справочники.Пользователи.НайтиПоНаименованию("Иванов Иван Иванович");

// Проверим права доступа на чтение
ДоступРазрешен = УправлениеДоступом.ЧтениеРазрешено(ДокументСсылка, ПроверяемыйПользователь);

Если ДоступРазрешен Тогда
    Сообщить("Пользователь имеет доступ к документу.");
Иначе
    Сообщить("Доступ к документу для данного пользователя ограничен.");
КонецЕсли;

Важные нюансы работы метода:

Способ №2: Прямой запрос к регистрам ключей доступа (производительный RLS)

В современных конфигурациях (таких как ERP 2, Комплексная автоматизация 2, Управление торговлей 11, Бухгалтерия предприятия 3.0) при включенном производительном режиме RLS права рассчитываются системой заранее и кэшируются в специальных служебных регистрах сведений.

Для проверки мы можем напрямую обратиться к двум регистрам:

  1. РегистрСведений.КлючиДоступаКОбъектам — хранит информацию о соответствии конкретных документов (объектов) и их хэш-ключей доступа.
  2. РегистрСведений.КлючиДоступаПользователей — связывает пользователей (или их группы доступа) со списком доступных им ключей.

Благодаря этому администратор под полными правами может написать один простой и очень быстрый запрос без необходимости переключения сеансов или запуска фоновых процессов. Проанализируем пример такого запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ Первые 1
    |	КлючиОбъектов.Ссылка ИЗ
    |	РегистрСведений.КлючиДоступаКОбъектам КАК КлючиОбъектов
    |	ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КлючиДоступаПользователей КАК КлючиПользователей
    |		ПО КлючиОбъектов.КлючДоступа = КлючиПользователей.КлючДоступа
    |ГДЕ
    |	КлючиОбъектов.Ссылка = &СсылкаНаДокумент
    |	И КлючиПользователей.Пользователь = &ПроверяемыйПользователь";

Запрос.УстановитьПараметр("СсылкаНаДокумент", ОбъектПроверки);
Запрос.УстановитьПараметр("ПроверяемыйПользователь", ТестируемыйПользователь);

РезультатЗапроса = Запрос.Выполнить();
ДоступЕсть = НЕ РезультатЗапроса.Пустой();

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

Способ №3: Запуск фонового задания под правами целевого пользователя (для старых конфигураций)

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

Рассмотрим пошагово, как это реализовать программно:

Шаг 1. Создание экспортной процедуры в общем модуле

Процедура должна быть размещена в общем модуле с флагом "Сервер" и вызывать проверку наличия документа в базе через запрос.


// Процедура должна быть доступна для фонового задания
Процедура ПроверитьДоступФоновое(ПараметрыПроверки, АдресРезультата) Экспорт
    
    СсылкаНаДокумент = ПараметрыПроверки.Ссылка;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |	Ссылка
        |ИЗ
        |	Документ.ЗаказПокупателя
        |ГДЕ
        |	Ссылка = &Ссылка";
        
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
    Результат = Запрос.Выполнить();
    
    ДоступЕсть = НЕ Результат.Пустой();
    ПоместитьВоВременноеХранилище(ДоступЕсть, АдресРезультата);
    
КонецПроцедуры

Шаг 2. Запуск фонового задания под правами тестируемого пользователя

В коде интерактивной обработки (откуда администратор запускает проверку) мы инициируем фоновое задание, передавая в метод ФоновыеЗадания.Выполнить() пользователя информационной базы:


АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
ПараметрыПроцедуры = Новый Структура("Ссылка", ПроверяемыйДокумент);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ПараметрыПроцедуры);
МассивПараметров.Добавить(АдресРезультата);

// Находим объект ПользовательИнформационнойБазы для авторизации задания
ИмяПользователяИБ = ПроверяемыйПользователь.Имя; // Справочник "Пользователи"
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИБ);

// Запуск задания под правами конкретного пользователя
НовоеЗадание = ФоновыеЗадания.Выполнить(
    "ИмяОбщегоМодуля.ПроверитьДоступФоновое", 
    МассивПараметров, 
    "ПроверкаДоступаПодПользователем", 
    ПользовательИБ
);

Попытка
    НовоеЗадание.ОжидатьЗавершения(10); // Ожидаем выполнения не более 10 секунд
    ДоступРазрешен = ПолучитьИзВременногоХранилища(АдресРезультата);
Исключение
    Сообщить("Ошибка выполнения проверки прав: " + ОписаниеОшибки());
КонецПопытки;

Этот метод абсолютно безопасен. Фоновое задание работает в изолированном контексте, использует реальное окружение прав тестируемого пользователя и гарантирует 100% достоверный результат.

Почему способ с подменой параметров сеанса опасен и не будет работать?

Среди разработчиков часто встречается идея временно подменить параметр сеанса (например, ПараметрыСеанса.ТекущийПользователь = ТестируемыйПользователь), выполнить обычный запрос с ключевым словом РАЗРЕШЕННЫЕ в текущем сеансе администратора, а затем вернуть параметр назад.

Настоятельно не рекомендуем использовать этот подход по следующим причинам:

  1. Неполнота данных и недостоверность: Современный RLS в БСП задействует десятки различных параметров сеанса (группы доступа, разрешенные организации, склады, виды доступа, кэшированные таблицы и т.д.). Все эти параметры инициализируются один раз при старте сеанса конкретного пользователя. Подменив только «Текущего пользователя», вы получите недостоверный результат проверки, так как остальные кэшированные параметры сеанса останутся от администратора.
  2. Угроза безопасности системы: Если в процессе выполнения запроса или подмены параметров возникнет непредвиденная ошибка базы данных (исключение), код возврата параметра в исходное состояние может не отработать. В результате сеанс администратора останется под правами обычного пользователя (или наоборот, обычный пользователь получит полные права), что нарушает безопасность информационной системы.
  3. Блокировки СУБД: Запись параметров сеанса в многопоточной среде может приводить к транзакционным блокировкам и существенно замедлять работу других пользователей.

Используйте проверенные штатные функции БСП или фоновые задания, чтобы гарантировать стабильность и безопасность вашей системы 1С!

← На главную