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