Начиная с версии платформы 8.3.21, в 1С появилась возможность использовать нативную авторизацию в HTTP-сервисах с помощью JWT-токенов (JSON Web Token), по аналогии с Google OAuth 2.0. Этот механизм позволяет отказаться от передачи логина и пароля в открытом виде или использования Basic-авторизации, заменяя их современным стандартом передачи данных о безопасности. Однако при первичной настройке многие разработчики сталкиваются с ошибками вида "Токен доступа недействителен. Некорректное значение параметра 'iss'" или ошибкой 402. В этой статье мы подробно разберем, как правильно настроить файл публикации, провести тестирование http сервисов (удобно через инструмент для анализа и отладки HTTP-запросов) и сформировать токен на стороне 1С.
Для активации возможности JWT-авторизации необходимо внести изменения в файл default.vrd. Основная сложность заключается в том, что документация не всегда содержит полные примеры структуры этого файла. Рассмотрим основные элементы, которые должны быть внутри тега <service> вашего HTTP-сервиса. Проанализируем ключевой узел <jwt>, который отвечает за проверку входящих токенов.
Важно помнить, что используемая платформой библиотека для работы с JWT принимает ключи исключительно в формате Base64. Если вы используете секретную строку, её необходимо предварительно закодировать. Посмотрим на пример настройки секции внутри default.vrd:
<jwt>
<issuer name="ssl">
<keyInformation>0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw=</keyInformation>
</issuer>
<accessTokenRecipientName>testservis</accessTokenRecipientName>
</jwt>
Разберем параметры подробнее:
ssl (не путать с публикацией HTTP сервиса с использованием клиентского SSL сертификата). Это "эмитент" токена, который проверяется при валидации поля iss в самом JWT.HS256.aud). Оно должно совпадать с тем, что вы будете записывать в токен при его генерации. Обычно это имя самого HTTP-сервиса.Для создания токена в 1С используется объект ТокенДоступа. Проанализируем процесс его программного формирования. Выясним причину, по которой стандартные примеры могут не работать: часто это связано с неверным форматом даты или отсутствием обязательных полей в полезной нагрузке.
Рассмотрим пример кода для генерации рабочего токена:
АлгоритмПодписи = АлгоритмПодписиТокенаДоступа.HS256;
ТокенДоступа = Новый ТокенДоступа;
// Указываем алгоритм в заголовке
ТокенДоступа.Заголовки.Вставить("alg", Строка(АлгоритмПодписи));
// Эмитент должен совпадать с настройкой в vrd (в 8.3.21 часто только "ssl")
ТокенДоступа.Эмитент = "ssl";
// Указываем получателя (аудиторию). Важно передавать именно как массив!
МассивПолучателей = Новый Массив;
МассивПолучателей.Добавить("testservis"); // Имя из accessTokenRecipientName
ТокенДоступа.Получатели = МассивПолучателей;
// Имя пользователя 1С, под которым будет выполнено соединение
// У этого пользователя в базе должен быть включен флаг "Аутентификация токеном доступа"
ТокенДоступа.КлючСопоставленияПользователя = "user1C";
// Работа со временем (Unix Timestamp)
// Время создания должно быть в формате UTC
ТекущаяДатаUTC = ТекущаяУниверсальнаяДата();
ВремяСоздания = Дата(1,1,1) + ТекущаяУниверсальнаяДатаВМиллисекундах()/1000 - Дата(1970,1,1,1,0,0);
ТокенДоступа.ВремяСоздания = ВремяСоздания;
ТокенДоступа.ВремяЖизни = 2592000; // Срок действия в секундах
ТокенДоступа.Идентификатор = Новый УникальныйИдентификатор;
// Подписываем ключом, который мы указали в vrd (в Base64)
ТокенДоступа.Подписать(АлгоритмПодписи, "0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw=");
ТекстТокена = Строка(ТокенДоступа);
Сообщить(ТекстТокена);
При использовании внешних систем генерации токенов или проверке на ресурсах вроде jwt.io, можно столкнуться с ошибкой "Invalid date". Выясним причину: согласно спецификации RFC 7519, поля дат (iat, exp, nbf) должны быть числового типа (NumericDate). Платформа 1С при создании токена через объект ТокенДоступа корректно упаковывает их, но если вы формируете JSON вручную, следите, чтобы значения не превращались в строки (в кавычках).
Для расчета корректного времени создания в формате Unix Timestamp (количество секунд с 01.01.1970), рекомендуется использовать функцию ТекущаяУниверсальнаяДатаВМиллисекундах(). Это позволит избежать проблем с часовыми поясами, когда сервер 1С считает, что токен "еще не создан" из-за разницы во времени между Москвой и UTC.
Если для HTTP-сервисов токен обычно передается в заголовке Authorization: Bearer <token>, то для Web-сервисов (WSDL) ситуация иная. Выясним, как передать токен при создании WSПрокси. Платформа поддерживает передачу токена прямо в строке URL.
Рассмотрим по шагам:
WSОпределения добавьте параметр AccessToken к адресу WSDL.WSПрокси также укажите URL с токеном, но уже без суффикса ?wsdl.Пример реализации:
ТокенДоступа = "ваш_сгенерированный_токен";
БазовыйURL = "http://server/base/ws/service.1cws";
URL_WSDL = БазовыйURL + "?wsdl&AccessToken=" + ТокенДоступа;
Определения = Новый WSОпределения(URL_WSDL, ИмяПользователя, Пароль);
// Для прокси используем URL без параметров wsdl
URL_Для_Прокси = БазовыйURL + "?AccessToken=" + ТокенДоступа;
Прокси = Новый WSПрокси(Определения, "Namespace", "ServiceName", "PortName",,,, URL_Для_Прокси);
В более поздних версиях платформы (8.3.23+) объект ТокенДоступа получил поддержку асимметричного алгоритма RS256. Это позволяет использовать пару "открытый/закрытый ключ". Подобные механизмы используются, например, при получении токена авторизации RuStore с использованием RSA-подписи. В файле default.vrd в этом случае указывается публичный ключ, а токен подписывается закрытым ключом на стороне издателя. Это значительно повышает безопасность, так как сервер 1С не хранит секрет, способный генерировать новые токены, а может только проверять подлинность существующих.
Подведем итог: для успешной JWT-авторизации в 1С необходимо обеспечить строгое соответствие эмитента (iss), аудитории (aud) и ключа подписи между файлом default.vrd и самим токеном. Использование нативного объекта ТокенДоступа упрощает эту задачу, автоматически соблюдая типы данных для технических полей.