В практике администрирования 1С часто возникает специфическая задача: необходимо наделить определенного сотрудника (например, финансового директора или главного бухгалтера) правом принудительно завершать работу всех остальных пользователей для выполнения критически важных операций. При этом давать такому пользователю полные права или права системного администратора крайне нежелательно из соображений безопасности. В данной статье мы подробно разберем, как реализовать этот функционал программными средствами, используя возможности платформы 1С:Предприятие 8.3.
Стандартная логика платформы 1С подразумевает, что управление сеансами — это прерогатива администратора. Обычный пользователь не может «видеть» чужие сеансы и тем более прерывать их. Однако технически задача «выгона» пользователей сводится к двум этапам: программному завершению активных сеансов и установке блокировки на новые подключения. Чтобы обычный пользователь смог это сделать, нам потребуется обойти проверку прав с помощью привилегированного режима.
Рассмотрим по шагам основные способы реализации этой задачи.
Это самый надежный способ с точки зрения программирования внутри конфигурации. Суть метода заключается в создании специальной процедуры, которая будет выполняться на сервере без проверки прав доступа текущего пользователя. Проанализируем, как это настроить:
Пример программного кода для принудительного завершения сеансов может выглядеть следующим образом:
Процедура ЗавершитьВсеСеансыКромеТекущего() Экспорт
// Получаем текущий номер сеанса, чтобы не выкинуть инициатора
НомерТекущегоСеанса = НомерСеансаИнформационнойБазы();
// Получаем список всех активных сеансов
Сеансы = ПолучитьСеансыИнформационнойБазы();
Для Каждого Сеанс Из Сеансы Цикл
Если Сеанс.НомерСеанса <> НомерТекущегоСеанса Тогда
Попытка
ЗавершитьСеанс(Сеанс);
Исключение
// Запись в журнал регистрации, если сеанс не удалось завершить
ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось завершить сеанс №" + Сеанс.НомерСеанса);
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
После создания такой процедуры в привилегированном модуле, достаточно вызвать ее из любой обработки, доступной нашему пользователю. Проверка прав на объект СеансИнформационнойБазы будет проигнорирована.
Выгнать пользователей — это только половина дела. Если не установить блокировку, они тут же зайдут обратно. Чтобы наш «Специалист по особым поручениям» мог работать монопольно, мы должны заблокировать вход для всех, кроме него самого.
Для этого используется объект БлокировкаУстановкиСоединений. Проанализируем алгоритм:
Рассмотрим пример кода для установки такой блокировки:
Процедура УстановитьБлокировкуДляФинДиректора() Экспорт
Блокировка = Новая БлокировкаУстановкиСоединений;
Блокировка.Установлена = Истина;
Блокировка.Начало = ТекущаяДата();
Блокировка.Сообщение = "База временно недоступна. Выполняются регламентные работы.";
Блокировка.КодРазрешения = "ADMIN_ACCESS"; // Тот самый код /UC
УстановитьБлокировкуУстановкиСоединений(Блокировка);
КонецПроцедуры
Важный нюанс: Чтобы сам пользователь (инициатор) смог войти в базу после того, как он из нее выйдет (или если его сеанс случайно прервется), в параметрах запуска его ярлыка 1С должен быть прописан ключ /UC ADMIN_ACCESS. Без этого кода база не пустит даже его, так как он не является администратором в системном понимании платформы.
Если база работает на SQL-сервере, наиболее эффективным методом управления сеансами является прямое обращение к кластеру серверов 1С через V83.COMConnector. Этот метод позволяет гарантированно «убивать» даже зависшие соединения, которые не реагируют на штатную команду ЗавершитьСеанс().
Для реализации этого метода нам потребуется знать имя сервера 1С и имя базы в кластере. Выясним, как это реализовать в коде:
Функция ВыгнатьВсехЧерезCOM(ИмяСервера, ИмяБазыАдмин, ПарольАдмина)
Connector = Новый COMОбъект("V83.COMConnector");
Agent = Connector.ConnectAgent(ИмяСервера);
Clusters = Agent.GetClusters();
// Обычно используется первый кластер в списке
Cluster = Clusters.GetValue(0);
Agent.Authenticate(Cluster, "", "");
РабочиеПроцессы = Agent.GetWorkingProcesses(Cluster);
Для Каждого Процесс Из РабочиеПроцессы Цикл
// Соединяемся с рабочим процессом
ОписаниеСоединения = Процесс.HostName + ":" + Формат(Процесс.MainPort, "ЧГ=0");
ConnectРабочийПроцесс = Connector.ConnectWorkingProcess(ОписаниеСоединения);
ConnectРабочийПроцесс.AddAuthentication(ИмяБазыАдмин, ПарольАдмина);
// Получаем описание информационной базы
ИнфоБаза = ConnectРабочийПроцесс.GetInfoBases();
// Находим нашу базу по имени и завершаем сеансы
// ... (логика перебора и вызова TerminateSession)
КонецЦикла;
КонецФункции
Этот способ требует хранения учетных данных администратора кластера (логин/пароль). Чтобы обычный пользователь их не узнал, этот код должен располагаться исключительно на стороне сервера в защищенном (привилегированном) модуле, а пароли могут храниться в зашифрованном виде или в параметрах сеанса.
Если ваша база файловая, то понятие «выгнать пользователя» технически сложнее. Платформа 1С в файловом режиме не имеет активного серверного процесса, который мог бы «обрубить» соединение. В этом случае используется механизм ожидания завершения работы.
В типовых конфигурациях на базе БСП это реализовано через проверку наличия файла 1Cv8.cdn или записи в константах. Каждое клиентское приложение в цикле (раз в минуту) проверяет, не установлен ли флаг завершения работы. Если флаг установлен, программа выдает предупреждение и закрывается через некоторое время.
Для обычного пользователя в файловой базе достаточно дать право на изменение соответствующей константы (через ту же привилегированную обработку). Однако помните, что «мгновенно» выгнать всех в файловом режиме не получится — придется ждать, пока у остальных сработает обработчик ожидания.
Предоставление возможности «выгонять всех» обычному пользователю — это риск. Проанализируем, как минимизировать негативные последствия:
ЖурналРегистрации каждое использование этой функции. Вы должны знать, кто и когда инициировал массовое завершение сеансов.ПоказатьОповещениеПользователя, чтобы у них было 2-3 минуты на сохранение своих документов.Мы рассмотрели несколько подходов к решению задачи. Наиболее оптимальным для программиста является сочетание привилегированного общего модуля и штатных механизмов блокировки соединений. Это позволяет обычному пользователю безопасно и эффективно перевести базу в монопольный режим, выполнить необходимые операции и вернуть систему в штатный режим работы, не обладая при этом избыточными правами администратора.