Рассмотрим распространенную ситуацию: 1С:Предприятие 7.7 установлена на терминальном сервере, базы файловые (DBF). В мониторе пользователей отображается только имя пользователя 1С (например, «Администратор») и имя сервера. Если несколько десятков сотрудников работают на сервере одновременно, и кто-то из них заходит в 1С под чужим логином или логином администратора, стандартными средствами 1С 7.7 выяснить истинного виновника практически невозможно. Платформа 7.7 не имеет встроенного механизма «Аутентификации Windows», который жестко связывал бы сеанс ОС и сеанс 1С.
Проанализируем различные способы решения этой задачи, от административных мер до написания кода и скриптов.
Прежде чем приступать к программированию, разберем базовые административные методы защиты.
usrdef. В журнале безопасности Windows можно будет посмотреть, кто из пользователей сервера открывал или изменял эти файлы.Не забываем, что из файловой базы можно просто скопировать отдельные файлы (DBF), подправить их сторонними утилитами, а потом записать обратно, даже не запуская 1С. Поэтому правильные права NTFS и аудит — это первая линия защиты.
Если необходимо программно зафиксировать, под какой учетной записью Windows был произведен вход в 1С, воспользуемся COM-объектами Windows Script Host (WSH). Рассмотрим подробнее, как получить данные из окружения операционной системы.
Вариант 1: Чтение переменных окружения
Мы можем обратиться к объекту Wscript.Shell и прочитать путь к профилю пользователя. Подцепим следующий код в глобальный модуль в процедуру ПриНачалеРаботыСистемы():
oShell = СоздатьОбъект("Wscript.Shell");
strUserProfile = oShell.ExpandEnvironmentStrings("%USERPROFILE%");
Сообщить("Профиль пользователя: " + strUserProfile);
Далее переменную strUserProfile можно проанализировать (извлечь имя пользователя из пути) и записать, например, в справочник или текстовый лог.
Вариант 2: Использование WScript.Network
Более надежный способ — использовать объект WScript.Network, который напрямую отдает имя пользователя ОС и домен, не требуя парсинга путей:
Net = СоздатьОбъект("WScript.Network");
ИмяПользователяОС = Net.UserName;
Домен = Net.UserDomain;
Сообщить("Вход выполнен пользователем Windows: " + ИмяПользователяОС);
Вариант 3: Определение компьютера-клиента RDP
Если пользователи работают через терминальный доступ (RDP), бывает полезно узнать не только имя пользователя на сервере, но и сетевое имя локального компьютера, с которого установлено подключение. Для этого прочитаем переменную окружения %CLIENTNAME%:
oShell = СоздатьОбъект("Wscript.Shell");
ИмяКлиента = oShell.ExpandEnvironmentStrings("%CLIENTNAME%");
Сообщить("Подключение с компьютера: " + ИмяКлиента);
Посмотрим на альтернативные подходы, если программирование внутри 1С не подходит (например, если пользователи могут запустить базу в обход измененной конфигурации).
Использование bat-файлов для запуска:
Можно организовать запуск 1С через командный bat-файл. Сценарий будет сначала записывать в независимый текстовый лог-файл текущую дату, время и имя пользователя Windows с помощью системной команды, а затем запускать 1С. Вход в базу можно жестко привязать к ярлыку конкретного пользователя, передавая ключи пользователя и пароля через командную строку.
Внешние компоненты (ВК):
С помощью внешних компонент (например, 1С++) можно напрямую считывать данные из реестра Windows. Обращаясь к ветке HKEY_CURRENT_USER, можно получить ключи, жестко привязанные к текущей терминальной сессии, что исключает ошибки при сложных сценариях авторизации.
При реализации записи имени пользователя ОС в 1С (например, в справочник активных сеансов), нужно учитывать одну особенность терминальных серверов. Иногда пользователи не выходят из 1С корректно, а просто закрывают окно терминала (нажимают "на крестик"). Сеанс остается висеть на сервере в состоянии Disconnected. Позже пользователь может зайти с другого компьютера или под другой учетной записью (если администратор перехватит сессию), при этом ПриНачалеРаботыСистемы() заново не отработает, и сохраненные данные станут неверными.
Чтобы избежать этой проблемы, можно циклически запускать код проверки имени пользователя и клиента (например, раз в 10 минут) через метод ОбработкаОжидания(). Это позволит актуализировать информацию о том, с какого рабочего места и под каким логином Windows в данный момент управляется конкретный сеанс 1С.