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