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

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← К списку

Приветствуем вас, коллеги! Сегодня мы рассмотрим очень важную и часто встречающуюся задачу в разработке на платформе 1С: Предприятие – ограничение доступа к справочнику. Эта проблема может возникнуть, когда необходимо, чтобы только определенные пользователи могли изменять данные в справочнике, а остальные имели к нему доступ только для просмотра. Мы подробно разберем различные подходы, их преимущества и недостатки, а также выясним, какие методы обеспечивают наиболее надежную защиту информации.

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

Права доступа и Роли: Фундамент безопасности 1С

В 1С действует принцип "по умолчанию запрещено всё, что не разрешено". Это означает, что для любого действия пользователя должны быть явно предоставлены права. Права доступа — это базовая сущность, определяющая, что пользователь может делать с объектами метаданных (справочниками, документами, отчетами) или с данными в них. Они могут быть общими (например, Администрирование) или объектными, такими как Чтение, Добавление, Изменение, Удаление для справочников.

Роли — это механизм, который объединяет набор прав доступа и назначается пользователям. Роли позволяют ограничивать доступ к виду объектов (например, ко всем элементам справочника Номенклатура), но не к конкретным элементам внутри этого справочника. Мы будем активно использовать роли в наших решениях.

Клиентские и Серверные проверки: В чем разница?

При решении задачи ограничения доступа мы столкнемся с двумя типами проверок:

  1. Клиентские проверки: Они выполняются на стороне клиента (в пользовательском интерфейсе). Например, установка свойства формы ТолькоПросмотр = Истина. Такие проверки визуально блокируют возможность изменения данных, делая кнопки "Записать", "Провести" недоступными. Однако, как мы увидим, они не обеспечивают полной защиты, так как могут быть обойдены другими способами взаимодействия с данными (например, через список, как было отмечено в обсуждении, или программно).
  2. Серверные проверки: Эти проверки выполняются на стороне сервера 1С. Они критически важны для обеспечения целостности и безопасности данных. Если серверная проверка запрещает действие (например, запись объекта), то оно не будет выполнено, независимо от действий пользователя на клиенте.

Мы выясним, почему для надежного ограничения доступа необходимо использовать именно серверные проверки.

Расширения конфигурации: Безопасные доработки

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

Методы ограничения доступа к справочнику

Давайте теперь разберем конкретные методы, которые помогут нам решить поставленную задачу.

1. Клиентская блокировка через свойство "ТолькоПросмотр" на форме

Один из самых простых и быстрых способов визуально ограничить редактирование элемента справочника — это установить свойство формы ТолькоПросмотр в значение Истина. Этот подход был предложен в самом начале обсуждения.

Мы можем установить это свойство в обработчике события формы ПриОткрытии. Давайте рассмотрим, как мы можем это реализовать, основываясь на различных условиях.

  1. Безусловная блокировка (для всех):

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

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецПроцедуры
    

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

  2. Блокировка на основе принадлежности пользователя к группе:

    Мы можем создать специальную группу пользователей (например, "Пользователи без права изменения") и проверять, принадлежит ли текущий пользователь к этой группе. Если да, то устанавливаем форму в режим только просмотра. Для этого нам понадобится функция на сервере, которая проверит принадлежность пользователя к группе.

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        Если Не ПользовательВГруппеИзменения() Тогда
            ЭтаФорма.ТолькоПросмотр = Истина;
        КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Функция ПользовательВГруппеИзменения()
        // Здесь реализуем логику проверки принадлежности пользователя к группе.
        // Например, можно использовать запросы к справочнику "ГруппыПользователей".
        // Для примера, всегда возвращаем Истина, если пользователь имеет право на изменение.
        Возврат ПравоДоступа("Изменение", Метаданные.Справочники.ВашСправочник);
    КонецФункции
    
  3. Блокировка на основе наличия определенной роли:

    Более гибкий подход — это проверка наличия у пользователя определенной роли, которая указывает на отсутствие прав на изменение. Мы можем создать в расширении специальную роль (например, "ТолькоПросмотрСправочника") и назначать ее тем, кому нужно ограничить доступ. Тогда проверка будет выглядеть так:

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        Если РольДоступна("ТолькоПросмотрСправочника") Тогда
            ЭтаФорма.ТолькоПросмотр = Истина;
        КонецЕсли;
    КонецПроцедуры
    

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

  4. Блокировка на основе профиля групп доступа (с использованием расширения):

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

    
    // В расширении, в обработчике события ПриОткрытии формы элемента справочника
    // (например, "Расш2_ПриОткрытииПосле" для подписки на событие "ПриОткрытии")
    &НаКлиенте
    Процедура Расш2_ПриОткрытииПосле(Отказ)
        Польз = ПользователиКлиент.ТекущийПользователь();
        ЭтаФорма.ТолькоПросмотр = Расш2_ЕстьВГруппе(Польз);
    КонецПроцедуры
    
    &НаСервере
    Функция Расш2_ЕстьВГруппе(Польз)
        Рез = Ложь;
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    ГруппыДоступаПользователи.Ссылка.Профиль КАК Профиль,
        |    ГруппыДоступаПользователи.Пользователь КАК Пользователь
        |ИЗ
        |    Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
        |
        |СГРУППИРОВАТЬ ПО
        |    ГруппыДоступаПользователи.Ссылка.Профиль,
        |    ГруппыДоступаПользователи.Пользователь
        |ИМЕЮЩИЕ
        |    ГруппыДоступаПользователи.Пользователь = &ТекущийПользователь"; // Добавим условие для текущего пользователя
    
        Запрос.УстановитьПараметр("ТекущийПользователь", Польз);
    
        Результат = Запрос.Выполнить();
        Выборка = Результат.Выбрать();
    
        Пока Выборка.Следующий() Цикл
            Если СтрНайти(Выборка.Профиль.Наименование, "БЕЗДОСТУПА") > 0 Тогда
                Рез = Истина;
                Прервать; // Если нашли нужный профиль, можно прервать цикл
            КонецЕсли;
        КонецЦикла;
    
        Возврат Рез;
    КонецФункции
    

    В этом примере мы проверяем, принадлежит ли текущий пользователь к группе доступа, профиль которой содержит подстроку "БЕЗДОСТУПА". Если да, то форма открывается только для просмотра.

Важное предупреждение: Как было справедливо замечено в обсуждении, установка свойства ТолькоПросмотр = Истина является клиентской визуальной блокировкой. Она не предотвратит изменение данных из других мест, например, из формы списка (через "Пометка на удаление"), через другие формы или программно. Для обеспечения настоящей защиты данных нам необходимы серверные проверки.

2. Надежное ограничение через подписки на события объекта

Для обеспечения надежной защиты данных нам необходимо использовать серверные проверки. Лучший способ для этого — механизм подписок на события. Этот механизм позволяет перехватывать действия с объектами конфигурации (такими как справочники) на сервере и выполнять в ответ определенный код. В нашем случае, мы будем использовать событие ПередЗаписью.

Рассмотрим, как это работает:

  1. Создание подписки: Мы создаем новую подписку на событие ПередЗаписью для нашего справочника. В качестве обработчика указываем серверную процедуру в общем модуле.
  2. Реализация логики проверки: В серверной процедуре-обработчике мы будем проверять права текущего пользователя. Если у пользователя нет необходимых прав на изменение, мы устанавливаем параметр Отказ = Истина, что предотвращает запись объекта.

Посмотрим на пример кода для такой подписки:


// В общем модуле (например, ОбщийМодульДоступа) создаем процедуру:
Процедура ПередЗаписьюСправочника(Источник, Отказ) Экспорт

    // Источник - это объект справочника, который пытаются записать
    // Отказ - булево значение, если Истина, то запись объекта будет отменена

    // Проверяем, имеет ли текущий пользователь право "Изменение" на этот справочник
    // Используем ПравоДоступа для точной проверки
    Если Не ПравоДоступа("Изменение", Источник.Метаданные()) Тогда
        Отказ = Истина;
        Сообщить("У вас нет прав на изменение элемента справочника " + Источник.Метаданные().Имя + "!");
    КонецЕсли;

    // Также можно проверять наличие определенной роли, если это более удобно
    // Например, если есть роль "ЗапретИзмененияСправочника"
    Если РольДоступна("ЗапретИзмененияСправочника") Тогда
        Отказ = Истина;
        Сообщить("Вам запрещено изменять элементы справочника " + Источник.Метаданные().Имя + "!");
    КонецЕсли;

    // Или проверять принадлежность к группе доступа, как в примере с профилем
    // Если Расш2_ЕстьВГруппе(ПользователиКлиент.ТекущийПользователь()) Тогда
    //     Отказ = Истина;
    //     Сообщить("Вам запрещено изменять элементы справочника " + Источник.Метаданные().Имя + "!");
    // КонецЕсли;

КонецПроцедуры

Преимущества этого подхода:

3. Комплексный подход: Управление ролями и расширения

Для более структурированного и поддерживаемого решения мы можем использовать комбинацию ролей, расширений и программных проверок.

Рассмотрим шаги, предложенные в одном из сообщений, с учетом лучших практик:

  1. Идентификация ролей с правами на изменение: Мы должны выяснить, какие существующие роли в конфигурации имеют права на Добавление/Изменение для нашего целевого справочника.
  2. Создание расширения и корректировка прав:
    • Создаем новое расширение конфигурации.
    • В расширение добавляем наш справочник.
    • Для всех ролей, которые изначально имели права на изменение этого справочника, в расширении убираем права на Изменение и Добавление, оставляя только Чтение, Просмотр, Ввод по строке. Это гарантирует, что эти роли не смогут изменять справочник.
    • Создаем в расширении новую роль (например, "РазрешеноИзменятьСправочник"). Этой новой роли мы даем полные права на Чтение, Добавление, Изменение, Удаление для нашего справочника.
  3. Назначение новой роли: Эту новую роль мы назначаем только тем пользователям, которым действительно разрешено изменять данные в справочнике.
  4. Программная проверка прав (опционально): Для дополнительной гибкости или для управления видимостью элементов на форме, мы можем использовать программные проверки в расширении, как мы рассматривали в пункте 1, но уже основываясь на нашей новой роли:
    
    &НаКлиенте
    Процедура Расш_ПриОткрытииПосле(Отказ)
        Если Не РольДоступна("РазрешеноИзменятьСправочник") Тогда
            ЭтаФорма.ТолькоПросмотр = Истина;
        КонецЕсли;
    КонецПроцедуры
    

    Или, что более корректно, использовать подписку на событие ПередЗаписью, проверяя наличие этой роли, как мы обсуждали ранее.

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

4. Расширенные механизмы: RLS и Функциональные опции

Помимо рассмотренных методов, платформа 1С предлагает более мощные механизмы для управления доступом, которые могут быть полезны в сложных сценариях:

  1. Ограничение доступа на уровне записей (RLS):

    RLS (Row-Level Security) — это механизм, который позволяет гибко настраивать права не только по видам объектов (например, ко всему справочнику), но и по данным внутри этих объектов. Например, мы можем разрешить пользователю видеть только те элементы справочника "Номенклатура", которые относятся к его складу, или изменять только те документы, которые он создал.

    RLS часто реализуется с использованием подсистемы "Управление доступом" из Библиотеки стандартных подсистем (БСП) через "Профили групп доступа" и "Группы доступа". Ограничение может быть наложено на права Чтение, Добавление, Изменение и Удаление. Это самый мощный и гибкий способ управления доступом, но и самый сложный в настройке.

  2. Функциональные опции:

    Функциональные опции — это механизм платформы, который позволяет управлять доступностью функционала конфигурации и видимостью элементов интерфейса в зависимости от настроек, хранящихся в информационной базе. Функциональные опции не ограничивают доступ к информации напрямую, но могут управлять ее отображением и доступностью кода, влияя на бизнес-логику и интерфейс. В контексте ограничения доступа к справочнику они могут быть использованы для скрытия или показа команд, связанных с изменением, но не для непосредственного запрета записи.

5. Программная проверка прав: РольДоступна vs ПравоДоступа

Когда мы пишем код для проверки прав, важно понимать разницу между методами РольДоступна() и ПравоДоступа().

Пример использования:


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

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

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

Рекомендации для эффективного управления доступом

Подводя итоги, давайте сформулируем основные рекомендации, которые помогут вам эффективно управлять доступом к справочникам и другим объектам в 1С:

  1. Используйте серверные проверки: Всегда отдавайте предпочтение подпискам на события (например, ПередЗаписью) для реализации логики ограничения доступа. Клиентские проверки (например, ТолькоПросмотр) используйте только для улучшения пользовательского опыта и визуальной индикации, но не как основной механизм защиты.
  2. Применяйте расширения: Все доработки, связанные с изменением прав или поведения типовых форм, реализуйте через расширения. Это значительно упрощает поддержку и обновление конфигурации.
  3. Минимально необходимое количество прав: Назначайте ролям только те права, которые действительно необходимы для выполнения их функций. Это не только повышает безопасность, но и способствует ускорению работы системы.
  4. Понимайте взаимосвязь механизмов: Для эффективного управления доступом важно четко понимать, как взаимодействуют роли, профили групп доступа, группы доступа, функциональные опции и RLS.
  5. Используйте ПравоДоступа() для точных проверок: Когда вам нужно проверить фактическую возможность действия над объектом метаданных, используйте метод ПравоДоступа().

Мы вместе разобрали различные способы ограничения доступа к справочнику в 1С, от простых клиентских блокировок до надежных серверных проверок и комплексных подходов с использованием расширений и ролей. Выбирайте метод, который наилучшим образом соответствует требованиям безопасности и сложности вашей задачи.

← К списку