Как реализовать авторизацию по API-ключу и идентификацию пользователей в веб-сервисах 1С

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

При разработке интеграционных решений на базе платформы 1С часто возникает задача разграничения доступа к данным: веб-сервисом пользуются разные внешние клиенты (покупатели, партнеры, сторонние системы), и каждому из них необходимо возвращать строго их собственный набор данных (например, заказы, взаиморасчеты или номенклатуру). Разберем, как правильно организовать прикладную авторизацию и передачу ключей доступа (API-key, токенов сессий) в сервисах 1С.

Ограничения стандартных SOAP Web-сервисов в платформе 1С

В веб-сервисах на базе протокола SOAP (объект метаданных Web-сервисы) разработчики часто пытаются использовать стандартные HTTP-заголовки или SOAP Headers для передачи токенов. Однако платформа 1С имеет жесткое архитектурное ограничение:

В модуле Web-сервиса нет прямого доступа к контексту HTTP-запроса и заголовкам. Платформа самостоятельно разбирает SOAP-конверт и передает в функцию модуля исключительно те параметры, которые описаны в свойствах соответствующей операции Web-сервиса или в связанном XDTO-пакете.

Способ 1. Передача API-ключа через параметры операций Web-сервиса (SOAP)

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

Разберем по шагам схему реализации:

  1. Публикация под техническим пользователем: чтобы внешним системам не требовалось авторизовываться под системными учетными записями 1С через базовую аутентификацию (Basic Auth), в файле публикации default.vrd на веб-сервере прописывается единый технический пользователь 1С с минимально необходимыми правами.
  2. Добавление параметра в операцию: в дереве метаданных в каждую функцию Web-сервиса добавляется строковый параметр (например, КлючДоступа или Token) типа string (http://www.w3.org/2001/XMLSchema).
  3. Хранение ключей в информационной базе: создаем непериодический регистр сведений (например, КлючиДоступаAPI) с измерениями Ключ (Строка) и ресурсами Контрагент (СправочникСсылка.Контрагенты), ДействуетДо (Дата), Заблокирован (Булево).
  4. Проверка прав в коде функции: при каждом входящем вызове первым шагом выполняется валидация переданного ключа.

Посмотрим на пример реализации серверной функции проверки и выборки данных:


Функция ПолучитьСписокЗаказов(КлючДоступа) Экспорт
    
    Контрагент = ПолучитьКонтрагентаПоКлючу(КлючДоступа);
    Если Контрагент = Неопределено Тогда
        ВызватьИсключение "Ошибка авторизации: неверный или недействительный API-ключ";
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ЗаказПокупателя.Ссылка КАК Заказ,
        |   ЗаказПокупателя.Номер КАК Номер,
        |   ЗаказПокупателя.Дата КАК Дата,
        |   ЗаказПокупателя.СуммаДокумента КАК Сумма
        |ИЗ
        |   Документ.ЗаказПокупателя КАК ЗаказПокупателя
        |ГДЕ
        |   ЗаказПокупателя.Контрагент = &Контрагент
        |   И НЕ ЗаказПокупателя.ПометкаУдаления";
        
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    ТаблицаДанных = Запрос.Выполнить().Выгрузить();
    
    // Формирование и возврат сериализованного ответа (XDTO или JSON)
    Возврат СериализоватьРезультат(ТаблицаДанных);
    
КонецФункции

Функция ПолучитьКонтрагентаПоКлючу(Знач КлючДоступа)
    
    Если ПустаяСтрока(КлючДоступа) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |   КлючиДоступаAPI.Контрагент КАК Контрагент
        |ИЗ
        |   РегистрСведений.КлючиДоступаAPI КАК КлючиДоступаAPI
        |ГДЕ
        |   КлючиДоступаAPI.Ключ = &Ключ
        |   И КлючиДоступаAPI.Заблокирован = ЛОЖЬ
        |   И (КлючиДоступаAPI.ДействуетДо >= &ТекущаяДата ИЛИ КлючиДоступаAPI.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1))";
        
    Запрос.УстановитьПараметр("Ключ", КлючДоступа);
    Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса());
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Контрагент;
    КонецЕсли;
    
    Возврат Неопределено;
    
КонецФункции

Способ 2. Использование HTTP-сервисов (REST) вместо SOAP

Если выбор протокола не ограничен требованиями сторонней системы, наиболее гибким и современным решением является использование объекта метаданных HTTP-сервисы вместо Web-сервисы.

Преимущество HTTP-сервисов заключается в наличии объекта HTTPСервисЗапрос, который предоставляет прямой доступ ко всем входящим HTTP-заголовкам через свойство Заголовки. Это позволяет клиентам передавать ключ в стандартных заголовках, таких как Authorization: Bearer <token> или X-API-Key, не засоряя тело запроса или параметры URL.

Рассмотрим пример чтения заголовка в обработчике метода HTTP-сервиса:


Функция ЗаказыGET(Запрос)
    
    // Извлекаем токен из заголовков запроса
    APIKey = "";
    Если Запрос.Заголовки.Свойство("X-API-Key") Тогда
        APIKey = Запрос.Заголовки["X-API-Key"];
    ИначеЕсли Запрос.Заголовки.Свойство("authorization") Тогда
        APIKey = СтрЗаменить(Запрос.Заголовки["authorization"], "Bearer ", "");
    КонецЕсли;
    
    Контрагент = ПолучитьКонтрагентаПоКлючу(APIKey);
    Если Контрагент = Неопределено Тогда
        Ответ = Новый HTTPСервисОтвет(401);
        Ответ.УстановитьТелоИзСтроки("{""error"": ""Не авторизован""}", "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
        Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
        Возврат Ответ;
    КонецЕсли;
    
    // Формирование успешного ответа
    СтрокаJSON = ПолучитьДанныеКонтрагентаJSON(Контрагент);
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки(СтрокаJSON, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Возврат Ответ;
    
КонецФункции

Способ 3. Подсистема внешних пользователей и RLS (Библиотека стандартных подсистем)

Если в конфигурации используется Библиотека стандартных подсистем (БСП), задачу можно решить на уровне системных прав:

  1. Включить подсистему Внешние пользователи в настройках БСП.
  2. Создать учетную запись внешнего пользователя для каждого контрагента и привязать к объекту справочника Контрагенты.
  3. Настроить ограничения доступа на уровне записей (RLS), где условие фильтрации документов строится по текущему внешнему пользователю.
  4. При вызове веб-сервиса клиент передает свой индивидуальный логин и пароль через стандартную HTTP Basic Authentication веб-сервера. Платформа 1С автоматически инициализирует сеанс с нужным внешним пользователем и применяет ограничения RLS.

Итоги

Проанализировав возможности платформы 1С, выделим главные правила построения сервисов:

  1. В классических SOAP Web-сервисах 1С заголовки недоступны — идентификатор (ключ или сессионный токен) обязательно передается в качестве явного параметра функции.
  2. Для работы с произвольными заголовками (X-API-Key, Authorization) следует использовать HTTP-сервисы.
  3. Для надежности архитектуры рекомендуется выполнять базовую авторизацию на веб-сервере под единым техническим пользователем, а прикладное разграничение данных выполнять внутри модуля сервиса по переданному токену.
← На главную