Приветствуем, коллеги! В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 часто возникает задача обеспечения безопасности и конфиденциальности данных. Типичный пример: в справочнике или документе присутствует табличная часть, содержащая учетные данные (например, логины и пароли сотрудников для доступа к внешним сервисам). Нам необходимо настроить интерфейс так, чтобы обычные пользователи видели вместо паролей «звездочки» (маску), а ответственные лица или авторы строк имели возможность просматривать и редактировать эти пароли в открытом виде.
В этой статье мы подробно разберем, как решить эту задачу на управляемых формах. Мы проанализируем ограничения платформы, рассмотрим несколько практических вариантов реализации — от простого визуального скрытия до построения максимально безопасной архитектуры, исключающей утечку данных на клиентскую сторону.
Прежде чем перейти к решениям, выясним причину, почему стандартные средства платформы не позволяют решить задачу «в лоб». У элемента формы типа «Поле ввода» (который используется в качестве колонки табличной части) есть замечательное свойство — РежимПароля. Если установить его в значение Истина, платформа автоматически заменяет все вводимые символы точками или звездочками.
Однако у этого свойства есть критическое ограничение: оно устанавливается для элемента формы (колонки) целиком. Платформа 1С:Предприятия не позволяет программно включать или выключать РежимПароля динамически для каждой строки отдельно в процессе отрисовки таблицы. Если мы включим этот режим для колонки, пароли скроются во всех строках. Если выключим — откроются тоже во всех. Поэтому нам придется использовать обходные пути.
Разберем самый быстрый способ визуальной маскировки данных, который отлично подходит для сценариев, где данные нужно закрыть исключительно от случайного просмотра (например, если за спиной пользователя могут стоять посторонние люди).
Идея заключается в динамической подмене отображаемого текста в ячейке с помощью условного оформления формы. Но здесь есть важнейший нюанс, о котором часто забывают начинающие разработчики. Если мы просто настроим условное оформление, изменяющее свойство Текст на "********", то при двойном клике по ячейке (входе в режим редактирования) платформа активирует реальное текстовое поле, и пользователь мгновенно увидит исходный пароль!
Чтобы избежать этой уязвимости, условное оформление должно накладываться комплексно. Выполним настройку по шагам:
ПриСозданииНаСервере).Объект.Доступы.Пароль)."••••••••").Истина (это заблокирует активацию поля ввода при клике).Давайте посмотрим на пример программной настройки такого оформления в модуле управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Очистим или подготовим правила условного оформления
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// 1. Указываем, какие свойства ячейки мы хотим изменить
ПолеТекст = ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Текст", "••••••••");
ПолеТолькоПросмотр = ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
// 2. Указываем поле таблицы, к которому применяется оформление
ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТабличнаяЧастьДоступыПароль");
ОформляемоеПоле.Использование = Истина;
// 3. Задаем условие: скрывать пароль для всех, кроме ответственного сотрудника
КомпоновочноеУсловие = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
КомпоновочноеУсловие.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Доступы.Сотрудник");
КомпоновочноеУсловие.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
КомпоновочноеУсловие.ПравоеЗначение = ПараметрыСеанса.ТекущийПользователь;
КомпоновочноеУсловие.Использование = Истина;
КонецПроцедуры
Этот способ прост в реализации, однако он решает проблему лишь на уровне интерфейса. Проанализируем его главный недостаток: реальные пароли все равно передаются с сервера на клиент в составе данных объекта. Продвинутый пользователь сможет легко извлечь их с помощью отладчика или простейшей внешней обработки.
Для создания по-настоящему безопасного решения нам необходимо полностью исключить передачу секретных данных на клиентский компьютер для тех строк, к которым у пользователя нет доступа. Реализуем это через подмену оригинальной колонки виртуальным реквизитом формы.
Разберем детальный алгоритм реализации этого метода по шагам:
ПарольОтображение.Пароль. Оригинальную колонку Пароль полностью скроем с формы (установим свойство Видимость в значение Ложь).ПриЧтенииНаСервере (или ПриСозданииНаСервере для новых объектов) выполним обход строк табличной части. Для тех строк, к которым у текущего пользователя есть права доступа, мы перенесем реальный пароль в колонку ПарольОтображение. Для запрещенных строк мы запишем в эту колонку маску "••••••••", а оригинальное значение в табличной части объекта на сервере временно очистим или заменим уникальным хэшем-заглушкой (например, "$$$HIDDEN_PASSWORD$$$").ПередЗаписьюНаСервере мы сравним значения. Если значение в ПарольОтображение равно заглушке, значит, пользователь не менял его (и не имел к нему доступа). В таком случае мы восстанавливаем оригинальный пароль из базы данных перед сохранением. Если же значение изменилось, мы записываем новый пароль.Посмотрим на программную реализацию этой логики. Напишем код для серверных обработчиков формы:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Заполняем виртуальную колонку и маскируем данные в объекте формы
Для Каждого СтрокаТЧ Из Объект.Доступы Цикл
Если ПользовательИмеетДоступ(СтрокаТЧ.Сотрудник) Тогда
// Пользователь имеет право видеть пароль
СтрокаТЧ.ПарольОтображение = СтрокаТЧ.Пароль;
Иначе
// Маскируем значение для клиента
СтрокаТЧ.ПарольОтображение = "••••••••";
// Очищаем реальное значение в данных формы на клиенте, чтобы исключить утечку
СтрокаТЧ.Пароль = "$$$HIDDEN_PASSWORD$$$";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Перед записью нам нужно восстановить оригинальные пароли для нередактируемых строк
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Доступы.НомерСтроки КАК НомерСтроки,
| Доступы.Пароль КАК ИсходныйПароль
|ИЗ
| Справочник.Контрагенты.Доступы КАК Доступы
|ГДЕ
| Доступы.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
ТаблицаИсходныхДанных = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаТЧ Из ТекущийОбъект.Доступы Цикл
СтрокаОтображения = Объект.Доступы.НайтиСтрокуПоИдентификатору(СтрокаТЧ.НомерСтроки);
Если СтрокаТЧ.Пароль = "$$$HIDDEN_PASSWORD$$$" Тогда
// Пользователь не имел доступа и не менял пароль. Восстанавливаем оригинал из базы
СтрокаПоиска = ТаблицаИсходныхДанных.Найти(СтрокаТЧ.НомерСтроки, "НомерСтроки");
Если СтрокаПоиска <> Неопределено Тогда
СтрокаТЧ.Пароль = СтрокаПоиска.ИсходныйПароль;
КонецЕсли;
Иначе
// Пользователь ввел новый пароль в виртуальную колонку
Если ПользовательИмеетДоступ(СтрокаТЧ.Сотрудник) Тогда
СтрокаТЧ.Пароль = СтрокаОтображения.ПарольОтображение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция ПользовательИмеетДоступ(СотрудникСтроки)
// Здесь реализуется логика проверки прав доступа
Возврат СотрудникСтроки = ПараметрыСеанса.ТекущийПользователь
Или РольДоступна("ПолныеПрава");
КонецФункции
Используя этот подход, мы гарантируем абсолютную безопасность конфиденциальных данных на клиенте. Неавторизованный пользователь получит с сервера лишь строковые заглушки, а реальные пароли останутся надежно защищены внутри серверного контекста.
Еще один эргономичный и современный подход — это использование кнопки-переключателя (например, в виде картинки с «глазом» или надписи «Показать») непосредственно в строке табличной части. Это избавляет интерфейс от перегруженности звездочками и позволяет пользователю точечно запрашивать просмотр пароля для конкретной строки.
Для реализации этого метода выполним следующие действия:
ПарольОтображение добавим в строку таблицы команду (кнопку) с действием ПоказатьПароль.ПарольОтображение только для этой конкретной строки.Посмотрим на пример клиент-серверного взаимодействия для реализации такой кнопки просмотра:
&НаКлиенте
Процедура ТаблицаДоступыПоказатьПароль(Команда)
ТекущаяСтрока = Элементы.ТаблицаДоступы.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Если пароль уже показан, скроем его обратно
Если ТекущаяСтрока.ПарольОтображение <> "••••••••" И ТекущаяСтрока.ПарольОтображение <> "" Тогда
ТекущаяСтрока.ПарольОтображение = "••••••••";
Возврат;
КонецЕсли;
// Запрашиваем реальное значение с сервера
РеальныйПароль = ПолучитьПарольСтрокиНаСервере(ТекущаяСтрока.ПолучитьИдентификатор());
Если РеальныйПароль = Неопределено Тогда
ПоказатьПредупреждение(, "Недостаточно прав для просмотра данного пароля!");
Иначе
ТекущаяСтрока.ПарольОтображение = РеальныйПароль;
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьПарольСтрокиНаСервере(ИдентификаторСтроки)
// Проводим авторизацию запроса на сервере
Если ПараметрыСеанса.ТекущийПользователь.Пустая() Тогда
Возврат Неопределено;
КонецЕсли;
// Получаем реальный пароль из базы данных по идентификатору
// (Вставьте сюда ваш запрос к БД с проверкой прав доступа пользователя к строке)
Возврат "РеальныйСекретныйПарольИзБД";
КонецФункции
Этот способ является стандартом де-факто для современных интерфейсов и личных кабинетов, обеспечивая идеальный баланс между удобством работы пользователей и требованиями безопасности информации.
Мы подробно проанализировали три отличных способа частичного скрытия паролей в табличных частях 1С. Выбирайте оптимальный вариант, исходя из требований к безопасности вашей системы: для простых интерфейсных задач отлично подойдет условное оформление, а для корпоративных решений с жесткими требованиями к разграничению доступа — архитектура на базе виртуальных реквизитов формы и серверного маскирования данных.