Почему аутентификация HTTP-сервисов по Bearer-токену перестала работать после обновления платформы 1С:Предприятие до версии 8.3.22 и выше?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на новые версии платформы 1С:Предприятие, начиная с 8.3.22, многие пользователи столкнулись с неожиданным поведением HTTP-сервисов, использующих аутентификацию по Bearer-токену. Ранее работавшие механизмы авторизации внезапно начали выдавать ошибку 401, при этом сервер игнорировал даже настроенные в VRD-файле логины и пароли. Давайте разберем эту проблему подробнее и выясним, в чем заключаются изменения.

Суть проблемы: Не работает Bearer-токен, выдается ошибка 401

Пользователи, обновившие платформу 1С:Предприятие до версий 8.3.22, 8.3.27 или новее, обнаружили, что их HTTP-сервисы, настроенные на работу с аутентификацией по Bearer-токену, перестают функционировать. Основные симптомы проблемы, с которыми сталкиваются разработчики и системные администраторы:

  1. При отправке HTTP-запроса с корректным Bearer-токеном в заголовке Authorization, платформа 1С возвращает ошибку 401 (Unauthorized). Это указывает на отказ в авторизации, несмотря на передачу токена.
  2. Если в запросе отсутствует токен или он пустой, доступ к HTTP-сервису может быть разрешен (при наличии других, например, анонимных, настроек или если сервис не требует аутентификации). Это крайне парадоксально, поскольку наличие токена приводит к отказу, а его отсутствие позволяет работать.
  3. Платформа безуспешно пытается авторизоваться на сервере, используя переданный токен. После нескольких неудачных попыток аутентификации, система может заблокировать пользователя, что создает дополнительные проблемы безопасности и доступности.
  4. При наличии Bearer-токена в запросе, платформа игнорирует настройки логина/пароля, указанные в файле vrd (Virtual Directory) для публикации HTTP-сервиса. Это означает, что даже если в vrd прописаны валидные учетные данные, платформа не пытается их использовать, если видит токен.

Все эти симптомы указывают на глубокие изменения в логике обработки аутентификации, которые нарушили обратную совместимость и требуют пересмотра существующих интеграционных решений.

Анализ изменений в платформе 1С:Предприятие 8.3.22+

Для того чтобы понять корень проблемы, рассмотрим ключевые изменения, внесенные в механизмы аутентификации платформы 1С:Предприятие, начиная с версии 8.3.22. Эти изменения были направлены на расширение возможностей безопасности и интеграции, но, как мы видим, привели к нежелательным побочным эффектам для существующих решений:

  1. Внедрение OpenID Connect и JWT-токенов: В версии 8.3.22 была значительно расширена поддержка протокола OpenID Connect и внедрена аутентификация по JWT (JSON Web Token), подобная той, что используется в протоколе Google OAuth 2.0. Это потребовало серьезных доработок в подсистеме аутентификации. Для сопоставления полей токена с полями пользователя информационной базы при аутентификации через OpenID Connect и JWT-токен было добавлено новое поле КлючиСопоставленияПользователя (UserMatchingKeys). Управление этими ключами выполняется только из встроенного языка 1С, что указывает на высокую степень детализации и гибкости настройки новой функциональности.
  2. Изменение приоритета аутентификации: С появлением новых механизмов изменился и порядок, в котором платформа 1С пытается аутентифицировать пользователя. Согласно документации 1С для версии 8.3.27 (и, по всей видимости, для 8.3.22 как предшествующей версии с аналогичными изменениями), приоритет отдается сначала токену сохраненной аутентификации, а затем JWT-токену. Критически важно понять: если аутентификация с помощью этих механизмов не выполнена (например, токен некорректен, просрочен или не соответствует формату JWT), дальнейшие способы аутентификации (например, по логину/паролю из VRD-файла или другим традиционным методам) просто не применяются. Это прямо объясняет, почему настройки из vrd игнорируются при наличии токена в запросе.
  3. Повышенная информативность ошибок: Разработчики платформы повысили детализацию сообщений об ошибках и информации, выводимой в технологический журнал. Это, безусловно, полезно для диагностики и может помочь нам более точно определить причину конкретной ошибки, однако это не решает саму проблему несовместимости механизмов.
  4. Усиление безопасности: В версии 8.3.22 также была повышена безопасность процедуры аутентификации тонкого и веб-клиентов при доступе к информационной базе по протоколу HTTP. Для передачи пароля теперь используется хеширование SHA-256 и шифрование AES-256 CBC. Эти изменения показывают общий вектор развития платформы в сторону более строгих стандартов безопасности и требуют от разработчиков учитывать эти нововведения.
  5. Проблемы с аутентификацией в 8.3.27: Отдельно отмечались проблемы с аутентификацией в облачном сервисе 1С:Фреш после обновления тонкого клиента до версии 8.3.27, связанные с изменением механизмов использования OpenID-аутентификации. Решения включали удаление параметра /OIDA- или изменение ссылки HTTP-сервиса для загрузки списка информационных баз. Хотя это напрямую не касается Bearer-токенов, это указывает на чувствительность новых механизмов аутентификации к изменениям и на то, что подобные «сюрпризы» могут возникать при переходе на новые версии.

Причины возникшей ситуации: Конфликт Bearer-токена с JWT

На основе всестороннего анализа изменений в платформе и сообщений пользователей, мы можем сформулировать основную и наиболее вероятную причину возникшей проблемы:

При внедрении полноценной поддержки JWT-аутентификации, платформа 1С:Предприятие 8.3.22 и последующих версий начала агрессивно интерпретировать любой токен, переданный в заголовке Authorization: Bearer ..., как попытку аутентификации посредством JWT (JSON Web Token). Это ключевое изменение в поведении. Даже если ваш HTTP-сервис изначально не был настроен на работу с JWT, а использовал простую Bearer-аутентификацию (например, на основе произвольной строки, которую затем вы обрабатывали в коде HTTP-сервиса), платформа 1С теперь пытается разобрать эту строку именно как JWT-токен, который, согласно стандартам, должен иметь определенную структуру и криптографическую подпись.

Если переданная строка не является валидным JWT-токеном (например, она не имеет правильной структуры из трех частей, разделенных точками, или не содержит корректной подписи, или полезная нагрузка (payload) не может быть корректно десериализована), аутентификация через JWT завершается неудачей. И, что самое важное, из-за измененного приоритета, платформа прекращает попытки аутентификации, игнорируя любые другие настроенные методы (например, стандартный логин/пароль из VRD-файла или HTTP Basic/Digest), и в результате возвращает ошибку 401 (Unauthorized).

Таким образом, произошло нарушение обратной совместимости: то, что раньше воспринималось как "просто Bearer-токен" и могло быть обработано на уровне вашего кода, теперь принудительно воспринимается платформой как специальный JWT-токен, и его несоответствие этому стандарту приводит к полному отказу в аутентификации. Это требует от разработчиков пересмотра подходов к аутентификации в своих интеграционных решениях.

Возможные пути решения проблемы

Для восстановления работоспособности HTTP-сервисов после обновления платформы 1С:Предприятие до версий 8.3.22+, рассмотрим несколько подходов, которые помогут нам адаптироваться к новым реалиям или обойти возникшую несовместимость. Для сложных систем, где требуется управление множеством сервисов, может быть полезно внедрить API-шлюз на платформе 1С, который централизует обработку запросов и аутентификацию.

1. Адаптация к JWT-аутентификации (рекомендуемый подход)

Если вы использовали Bearer-токены для аутентификации, наиболее логичным, безопасным и соответствующим новому функционалу платформы будет полноценный переход на использование JWT. Этот подход позволит вам воспользоваться преимуществами современных стандартов безопасности и глубокой интеграцией с платформой 1С. Это потребует следующих шагов:

  1. Генерация корректных JWT-токенов: На стороне клиентского приложения или службы, которая генерирует токены, необходимо настроить создание именно JWT-токенов. JWT должен содержать три части: заголовок (Header), полезную нагрузку (Payload) с необходимыми данными для аутентификации (например, имя пользователя, ID, роли, срок действия) и подпись (Signature). Подпись должна быть сгенерирована с использованием секретного ключа, известного только серверу и приложению, как это подробно показано в примере получения токена авторизации для RuStore.
  2. Настройка платформы 1С для работы с JWT:
    • В информационной базе 1С необходимо настроить механизмы распознавания и валидации JWT-токенов. Это включает создание или использование существующего метода аутентификации, который будет проверять полученный JWT.
    • Возможно, потребуется использование поля КлючиСопоставленияПользователя для связывания данных из полезной нагрузки JWT с пользователями информационной базы 1С. Это выполняется через встроенный язык. Для этого нам понадобится извлечь информацию из токена и сопоставить ее с существующими пользователями 1С.
    • Пример условного кода, иллюстрирующего процесс получения и базовой валидации JWT-токена в обработчике HTTP-сервиса (обратите внимание, что полная реализация валидации JWT, включая проверку подписи, сроков действия и издателя, может быть достаточно сложной и, возможно, потребует внешней компоненты или библиотеки):
      
      // Функция для получения токена из заголовка HTTP-запроса
      Функция ПолучитьJWTИзЗапроса(Запрос)
          // Получаем значение заголовка 'Authorization'
          ЗаголовокАвторизации = Запрос.Заголовки["Authorization"];
          Если НЕ ЗначениеЗаполнено(ЗаголовокАвторизации) Тогда
              // Если заголовок пуст, токен отсутствует
              Возврат Неопределено;
          КонецЕсли;
      
          // Проверяем, начинается ли заголовок с 'Bearer '
          Если НачинаетсяС(ЗаголовокАвторизации, "Bearer ") Тогда
              // Извлекаем сам токен, обрезая префикс 'Bearer '
              Возврат Сред(ЗаголовокАвторизации, СтрДлина("Bearer ") + 1);
          Иначе
              // Если формат заголовка не соответствует 'Bearer', возвращаем Неопределено
              Возврат Неопределено;
          КонецЕсли;
      КонецФункции;
      
      // Условная функция для валидации JWT
      // В реальном коде здесь должна быть полноценная логика:
      // 1. Декодирование токена (получение заголовка и полезной нагрузки).
      // 2. Проверка подписи токена с использованием секретного ключа.
      // 3. Проверка срока действия (exp) и других стандартных полей (iss, aud).
      // 4. Проверка специфичных для вашего приложения клеймов.
      Функция ВалидироватьJWT(ТокенJWT, СекретныйКлюч)
          Попытка
              // Предположим, у нас есть Объект/Метод для работы с JWT (например, внешняя компонента или сложная реализация на встроенном языке)
              // Пример: СтруктураТокена = Новый JWTДекодер().Декодировать(ТокенJWT);
              // Для упрощения, предположим, что это некая функция платформы или библиотеки,
              // которая возвращает Структуру с полями Header и Payload, если токен валиден.
              // Если токен валиден и успешно разобран, возвращаем Структуру с данными пользователя.
              // Иначе - Неопределено.
                              
              // Пример псевдокода для декодирования и валидации:
              ДекодированныйТокен = Новый Структура(); // Здесь будет результат декодирования
              // ... Здесь логика декодирования JWT (Header.Payload.Signature)
                              
              // Проверка подписи:
              Если НЕ ПроверитьПодписьJWT(ТокенJWT, СекретныйКлюч) Тогда // Условная функция, которая проверяет подпись
                  ЗаписьЖурналаРегистрации("Аутентификация", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка валидации JWT: неверная подпись.");
                  Возврат Неопределено;
              КонецЕсли;
      
              // Извлечение Payload для дальнейших проверок
              ПолезнаяНагрузка = ПолучитьPayloadИзJWT(ТокенJWT); // Условная функция
              Если ПолезнаяНагрузка = Неопределено Тогда
                  ЗаписьЖурналаРегистрации("Аутентификация", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка валидации JWT: не удалось извлечь Payload.");
                  Возврат Неопределено;
              КонецЕсли;
      
              // Проверка срока действия (exp)
              Если ПолезнаяНагрузка.Свойство("exp") И ПолезнаяНагрузка.exp < ТекущаяДата() Тогда
                  ЗаписьЖурналаРегистрации("Аутентификация", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка валидации JWT: токен просрочен.");
                  Возврат Неопределено;
              КонецЕсли;
                              
              // Дополнительные проверки (издатель, аудитория и т.д.)
              // Если все проверки пройдены, возвращаем полезную нагрузку токена
              Возврат ПолезнаяНагрузка; 
      
          Исключение Как Искл
              // Ошибка при обработке JWT (например, неверный формат)
              ЗаписьЖурналаРегистрации("Аутентификация", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка обработки JWT: " + Искл.Описание);
              Возврат Неопределено;
          КонецПопытки;
          Возврат Неопределено;
      КонецФункции;
                      
      // Процедура обработки запроса HTTP-сервиса
      Процедура ОбработатьЗапрос(Запрос, Ответ)
          // Получаем JWT-токен из заголовка запроса
          ТокенJWT = ПолучитьJWTИзЗапроса(Запрос);
                          
          Если ТокенJWT = Неопределено Тогда
              // Если токен отсутствует или не в формате Bearer, платформа 1С может попытаться
              // использовать другие методы аутентификации, но если это не сработает,
              // или если нам нужно только JWT, возвращаем 401.
              // В версиях 8.3.22+ без токена может сработать аутентификация из vrd.
              Ответ.УстановитьСтатус(401);
              Ответ.УстановитьТелоИзСтроки("Требуется аутентификация (JWT)");
              Возврат;
          КонецЕсли;
      
          // Валидируем полученный JWT-токен
          ПараметрыПользователя = ВалидироватьJWT(ТокенJWT, "ВашОченьСекретныйКлючДляJWT"); // Используйте надежный секретный ключ
                          
          Если ПараметрыПользователя = Неопределено Тогда
              // Если валидация не прошла, токен недействителен
              Ответ.УстановитьСтатус(401);
              Ответ.УстановитьТелоИзСтроки("Недействительный или просроченный токен.");
              Возврат;
          КонецЕсли;
      
          // Если JWT валиден, устанавливаем текущего пользователя 1С
          // на основе данных из ПараметрыПользователя (полезной нагрузки JWT).
          // Например, если в Payload есть поле "ИмяПользователя":
          Если ПараметрыПользователя.Свойство("ИмяПользователя") Тогда
              ИмяПользователяИзТокена = ПараметрыПользователя.ИмяПользователя;
              Попытка
                  // Используем методы для установки пользователя (например, при помощи ОбщегоНазначения.УстановитьПривилегированныйРежим(Истина) и далее ОбработкаВнешнихЗапросов.УстановитьПользователя(ИмяПользователяИзТокена))
                  // или ищем пользователя по имени и устанавливаем его для текущего сеанса.
                  // ... Логика поиска и установки пользователя 1С по ИмяПользователяИзТокена ...
                  // Например, можно получить объект Пользователь, используя Справочники.Пользователи.НайтиПоНаименованию()
                  // и затем привязать его к текущему сеансу, если необходимо.
                  // Если аутентификация прошла успешно, продолжим обработку запроса.
                                  
                  // Здесь должна быть ваша основная логика HTTP-сервиса
                  Ответ.УстановитьСтатус(200);
                  Ответ.УстановитьТелоИзСтроки("Добро пожаловать, " + ИмяПользователяИзТокена + "!");
      
              Исключение Как Искл
                  // Ошибка при установке пользователя 1С (например, пользователь не найден)
                  ЗаписьЖурналаРегистрации("Аутентификация", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка установки пользователя 1С по JWT: " + Искл.Описание);
                  Ответ.УстановитьСтатус(401);
                  Ответ.УстановитьТелоИзСтроки("Ошибка при аутентификации пользователя в 1С.");
              КонецПопытки;
          Иначе
              Ответ.УстановитьСтатус(401);
              Ответ.УстановитьТелоИзСтроки("Токен не содержит необходимого поля 'ИмяПользователя'.");
          КонецЕсли;
      КонецПроцедуры;
      

2. Отказ от передачи токена в заголовке Authorization (для использования традиционной аутентификации)

Если для вашего HTTP-сервиса достаточно аутентификации по логину/паролю, настроенной в файле vrd, и вы не хотите или не можете перейти на JWT, то самым простым и быстрым решением будет полностью исключить передачу заголовка Authorization: Bearer <токен> в запросах к HTTP-сервису. Это позволит платформе не инициировать JWT-валидацию и вернуться к традиционным методам аутентификации.

  1. Модификация клиентского приложения: Измените клиентское приложение так, чтобы оно не формировало и не отправляло заголовок Authorization с Bearer-токеном. Это критически важно, поскольку любое присутствие такого заголовка будет провоцировать попытку JWT-аутентификации.
  2. Проверка настроек VRD: Убедитесь, что в файле публикации вашего HTTP-сервиса (vrd) корректно настроена аутентификация по логину/паролю или другому приемлемому для вас методу, например, как это делается при публикации с использованием клиентского SSL-сертификата. Мы должны явно указать учетные данные, которые платформа будет использовать. Например, в файле vrd должны присутствовать следующие параметры:
    
    
    
        MyService
        
        МойПользователь 
        МойПароль 
        Standard 
    
    

    Если платформа не обнаружит Bearer-токен в запросе, она вернется к обработке других механизмов аутентификации, включая стандартный логин/пароль из vrd.

3. Временный откат платформы (крайняя мера)

Если у вас нет возможности оперативно переработать систему аутентификации или внести изменения в клиентские приложения, как временную меру можно рассмотреть откат платформы 1С:Предприятие до версии, предшествующей 8.3.22 (например, 8.3.21 или более ранней). Это позволит восстановить работоспособность существующих интеграций без изменений кода. Однако мы подчеркиваем, что это не является долгосрочным решением, так как вы не сможете использовать преимущества, исправления ошибок и новые возможности более свежих версий платформы. Мы рекомендуем рассмотреть этот вариант только как временное решение для восстановления работоспособности в экстренных случаях.

Заключение

Изменения в механизмах аутентификации платформы 1С:Предприятие, начиная с версии 8.3.22, являются значительными и требуют повышенного внимания при обновлении. Внедрение JWT-аутентификации изменило порядок обработки Bearer-токенов, заставляя платформу пытаться интерпретировать их как JWT. Если ваши Bearer-токены не соответствуют стандарту JWT, это приведет к ошибкам 401 и полному игнорированию других, ранее работавших, методов аутентификации.

Мы настоятельно рекомендуем пересмотреть вашу стратегию аутентификации и, по возможности, перейти на использование полноценных JWT-токенов, адаптируя как клиентские приложения, генерирующие токены (подобно решениям для интеграции с Google Таблицами через сервисный аккаунт), так и конфигурацию 1С для их валидации. В противном случае, если вы желаете использовать традиционную аутентификацию по логину/паролю, убедитесь, что вы не передаете заголовок Authorization: Bearer <токен> в HTTP-запросах.

Всегда внимательно анализируйте технологический журнал и сообщения об ошибках, так как в новых версиях 1С повышена их информативность, что может существенно помочь в более точной диагностике и поиске решения возникшей проблемы.

← На главную