При интеграции систем 1С:Предприятие с внешними веб-сайтами и сервисами по API разработчики часто сталкиваются с необходимостью отправки запросов по защищенному протоколу HTTPS. На этапе разработки в файловой базе или при тестировании кода на клиенте всё может работать безупречно. Однако при переносе функционала в рабочий клиент-серверный режим (например, при вызове интеграции в модуле объекта при проведении документа) система внезапно выдает ошибку компиляции: «Переменная не определена (СпособВыбораСертификатаWindows)».
В этой статье мы подробно разберем причины возникновения данной ошибки, проанализируем контекст выполнения кода на клиенте и сервере, а также рассмотрим несколько эффективных способов решения проблемы с предоставлением готовых примеров кода.
Для того чтобы понять природу ошибки, обратимся к механизму работы платформы 1С:Предприятие. Проведение документов, выполнение регламентных заданий, а также большинство бизнес-процедур выполняются строго в серверном контексте. Серверный код компилируется на стороне сервера приложений 1С.
Системное перечисление СпособВыбораСертификатаWindows (со значениями Авто и Выбирать) предназначено для интерактивного взаимодействия с пользователем через операционную систему MS Windows. Согласно официальной документации платформы 1С, доступность этого перечисления ограничена следующими контекстами:
На сервере приложений 1С данного типа данных попросту не существует. Когда компилятор сервера встречает конструкцию СпособВыбораСертификатаWindows.Авто, он не может сопоставить это выражение ни с одним известным ему серверным объектом или перечислением, что и приводит к ошибке «Переменная не определена».
Рассмотрим исходный проблемный участок кода, который часто пишется разработчиками по аналогии с клиентскими процедурами:
Если ЗащищенноеСоединение Тогда
// Данная строка вызовет ошибку компиляции на сервере:
ЗащСоединение = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто),
Новый СертификатыУдостоверяющихЦентровWindows()
);
Отправка = Новый HTTPСоединение(АдресСайта, 443, , , , , ЗащСоединение);
Иначе
Отправка = Новый HTTPСоединение(АдресСайта);
КонецЕсли;
Давайте разберем по шагам, как можно обойти это ограничение и запустить защищенное соединение на стороне сервера.
Самый простой способ исправить синтаксическую ошибку без изменения логики поиска сертификата в операционной системе Windows — убрать явное указание способа выбора сертификата из параметров конструктора.
Если вызвать конструктор объекта СертификатКлиентаWindows без параметров, платформа по умолчанию применит автоматический поиск сертификата в системном хранилище. Такой код успешно скомпилируется и будет работать на сервере под управлением ОС Windows:
Если ЗащищенноеСоединение Тогда
// Используем конструкторы без параметров, доступные на сервере
СертификатКлиента = Новый СертификатКлиентаWindows();
СертификатыУЦ = Новый СертификатыУдостоверяющихЦентровWindows();
ЗащСоединение = Новый ЗащищенноеСоединениеOpenSSL(СертификатКлиента, СертификатыУЦ);
Отправка = Новый HTTPСоединение(АдресСайта, 443, , , , , ЗащСоединение);
Иначе
Отправка = Новый HTTPСоединение(АдресСайта);
КонецЕсли;
Этот вариант отлично подходит, если сервер 1С работает под управлением ОС Windows и вам действительно требуется обращаться к локальному хранилищу сертификатов операционной системы.
Проанализируем архитектуру интеграции с внешними веб-сайтами. В 99% случаев для отправки запросов по протоколу HTTPS (например, к API платежных систем, службам доставки, CRM-системам или маркетплейсам) клиентский сертификат со стороны 1С не требуется.
Клиентский сертификат необходим только при использовании двусторонней SSL-аутентификации (mTLS), когда целевой веб-сервер требует строгого подтверждения личности отправителя с помощью его личного закрытого ключа. Если сайт этого не требует, достаточно пройти стандартную одностороннюю проверку сертификата самого сайта.
Для стандартного HTTPS-соединения мы можем инициализировать защищенное соединение по умолчанию, вообще не передавая параметры в конструктор ЗащищенноеСоединениеOpenSSL:
Если ЗащищенноеСоединение Тогда
// Инициализируем защищенное соединение по умолчанию.
// Платформа сама проверит сертификат сайта по системным правилам.
ЗащСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Отправка = Новый HTTPСоединение(АдресСайта, 443, , , , , ЗащСоединение);
Иначе
Отправка = Новый HTTPСоединение(АдресСайта);
КонецЕсли;
Если вам все же необходимо явно указать использование доверенных удостоверяющих центров операционной системы, но при этом отказаться от передачи клиентского сертификата (поскольку он не нужен), используйте значение Неопределено в качестве первого параметра:
Если ЗащищенноеСоединение Тогда
СертификатыУЦ = Новый СертификатыУдостоверяющихЦентровWindows();
ЗащСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, СертификатыУЦ);
Отправка = Новый HTTPСоединение(АдресСайта, 443, , , , , ЗащСоединение);
КонецЕсли;
Современные тенденции автоматизации бизнеса часто предполагают перевод серверов 1С:Предприятие на операционные системы семейства Linux (например, Ubuntu, CentOS, RedHat).
Если ваш сервер 1С работает под управлением Linux, использование любых объектов с суффиксом Windows (таких как СертификатКлиентаWindows или СертификатыУдостоверяющихЦентровWindows) приведет к ошибке времени выполнения (Runtime Error) вида: «Использование сертификатов ОС Windows не поддерживается на данной платформе».
Чтобы сделать код надежным и кроссплатформенным, рекомендуется использовать программные интерфейсы Библиотеки стандартных подсистем (БСП). В БСП реализован специальный метод общего назначения, который автоматически определяет тип операционной системы сервера и возвращает корректно инициализированный объект защищенного соединения:
Если ЗащищенноеСоединение Тогда
// Метод БСП автоматически вернет корректный объект защищенного соединения
// как для серверов на базе ОС Windows, так и для серверов на ОС Linux.
ЗащСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
Отправка = Новый HTTPСоединение(АдресСайта, 443, , , , , ЗащСоединение);
Иначе
Отправка = Новый HTTPСоединение(АдресСайта);
КонецЕсли;
Если в вашей конфигурации не используется БСП, вам придется вручную реализовать проверку операционной системы на сервере с помощью метода ПолучитьИнформациюЭкрановКлиента() или через анализ системных свойств, чтобы использовать СертификатыУдостоверяющихЦентровLinux в случае работы на Linux.
Перенос кода интеграции из файловой базы 1С в клиент-серверный вариант (SQL) часто вскрывает дополнительные технические нюансы, о которых необходимо знать заранее:
USR1CV8). Если вашему внешнему сайту действительно требовался локальный сертификат, установленный в вашей системе, убедитесь, что этот сертификат импортирован в хранилище сертификатов именно того пользователя, под которым работает служба сервера 1С..pem или .crt), убедитесь, что у пользователя USR1CV8 есть права на чтение директории, в которой расположены эти файлы на сервере.
ПутьКСертификатуУЦ = "C:\Certs\ca-bundle.crt"; // путь на диске сервера
СертификатыУЦ = Новый СертификатыУдостоверяющихЦентровФайл(ПутьКСертификатуУЦ);
ЗащСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, СертификатыУЦ);
Для исправления ошибки «Переменная не определена (СпособВыбораСертификатаWindows)» придерживайтесь следующего алгоритма действий:
Новый ЗащищенноеСоединениеOpenSSL() без передачи параметров.СпособВыбораСертификатаWindows.Авто и оставьте пустые скобки: Новый СертификатКлиентаWindows().ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение().