JWT авторизация в http-сервисе 8.3.21
В 8.3.21 появилась нативная авторизация в http-сервисе с помощью JWT-токена. Кто знает как настроить это в файле default.vrd? На ИТС нет примера, у самого не получилось, 2 дня мучаюсь - при обращении к сервису с токеном пишет ошибку 402. "Токен доступа недействителен.Некорректное значение параметра 'iss'"
Конструкция в default.vrd вот такая
<accessTokenAuthentication>
<issuers>
<issuer name="TEST" keyInformation="testwsfjwpfwjfpweojfpjpeo2323operj2p3r"/>
</issuers>
</accessTokenAuthentication>
Собственно, без этой конструкции такое же сообщение )
Конструкция в default.vrd вот такая
<accessTokenAuthentication>
<issuers>
<issuer name="TEST" keyInformation="testwsfjwpfwjfpweojfpjpeo2323operj2p3r"/>
</issuers>
</accessTokenAuthentication>
Собственно, без этой конструкции такое же сообщение )
По теме из базы знаний
Найденные решения
С партнёрского от 1С:
Ну и на скриншоте пример рабочего vrd
Добрый день.
"iss": "issuer"
В токене поле "iss" должно быть равно "ssl".
Используемая для работы с JWT библиотека принимает ключи только в формате BASE64. Попробуйте заменить формат ключа в коде и в vrd-файле. Например:
ТокенДоступа.Подписать(АлгоритмПодписиТокенаДоступа.HS256, "EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p");
<accessTokenAuthentication>
<issuers>
<issuer
name="ssl"
authenticationClaimName="sub"
authenticationUserPropertyName="name"
keyInformation="EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p"
/>
</issuers>
<accessTokenRecepientName>"token"</accessTokenRecepientName>
</accessTokenAuthentication>
Показать"iss": "issuer"
В токене поле "iss" должно быть равно "ssl".
Используемая для работы с JWT библиотека принимает ключи только в формате BASE64. Попробуйте заменить формат ключа в коде и в vrd-файле. Например:
ТокенДоступа.Подписать(АлгоритмПодписиТокенаДоступа.HS256, "EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p");
<accessTokenAuthentication>
<issuers>
<issuer
name="ssl"
authenticationClaimName="sub"
authenticationUserPropertyName="name"
keyInformation="EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p"
/>
</issuers>
<accessTokenRecepientName>"token"</accessTokenRecepientName>
</accessTokenAuthentication>
Ну и на скриншоте пример рабочего vrd
Прикрепленные файлы:
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Раскодируйте из base64 первые две части Вашего токена, убедитесь, что они представляют из себя синтаксически правильные json - сообщения.
Проверьте совпадение имени эмитента в токене (заявка/JWT claim "iss") и в файле default.vrd
Попробуйте делать токены, не используя символов кириллицы (только из английских букв).
Проверьте совпадение имени эмитента в токене (заявка/JWT claim "iss") и в файле default.vrd
Попробуйте делать токены, не используя символов кириллицы (только из английских букв).
(5) конечно, я проверял содержимое токена на jwt.io
Токены верные и их "едят" другие, не1С-системы
Внутри нет кириллицы, а так же на всякий случай нет цифр, пробелов и символов, отличных от английских букв в клайме iss.
Я не знаю как правильно оформлять файл default.vrd в плане настройки на JWT-токены. Даже на ИТС нет образца.
Токены верные и их "едят" другие, не1С-системы
Внутри нет кириллицы, а так же на всякий случай нет цифр, пробелов и символов, отличных от английских букв в клайме iss.
Я не знаю как правильно оформлять файл default.vrd в плане настройки на JWT-токены. Даже на ИТС нет образца.
С партнёрского от 1С:
Ну и на скриншоте пример рабочего vrd
Добрый день.
"iss": "issuer"
В токене поле "iss" должно быть равно "ssl".
Используемая для работы с JWT библиотека принимает ключи только в формате BASE64. Попробуйте заменить формат ключа в коде и в vrd-файле. Например:
ТокенДоступа.Подписать(АлгоритмПодписиТокенаДоступа.HS256, "EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p");
<accessTokenAuthentication>
<issuers>
<issuer
name="ssl"
authenticationClaimName="sub"
authenticationUserPropertyName="name"
keyInformation="EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p"
/>
</issuers>
<accessTokenRecepientName>"token"</accessTokenRecepientName>
</accessTokenAuthentication>
Показать"iss": "issuer"
В токене поле "iss" должно быть равно "ssl".
Используемая для работы с JWT библиотека принимает ключи только в формате BASE64. Попробуйте заменить формат ключа в коде и в vrd-файле. Например:
ТокенДоступа.Подписать(АлгоритмПодписиТокенаДоступа.HS256, "EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p");
<accessTokenAuthentication>
<issuers>
<issuer
name="ssl"
authenticationClaimName="sub"
authenticationUserPropertyName="name"
keyInformation="EgH23sF8nL3xEGT2kEmAgxWyaKWvcf3p"
/>
</issuers>
<accessTokenRecepientName>"token"</accessTokenRecepientName>
</accessTokenAuthentication>
Ну и на скриншоте пример рабочего vrd
Прикрепленные файлы:
(8) Спасибо!
Если про ключ в формате base64 я догадался, то о том, что значение iss всегда должно быть равно "ssl" (то есть прибито гвоздями в платформе) - догадаться не смог. Это значит, что сторонние готовые токены использовать не удастся, только свои, самодельные.
Итак, работающий кусок default.vrd
Чтобы сгенерировать токен под ЭТУ настройку, используется вот такой код 1С
Если про ключ в формате base64 я догадался, то о том, что значение iss всегда должно быть равно "ssl" (то есть прибито гвоздями в платформе) - догадаться не смог. Это значит, что сторонние готовые токены использовать не удастся, только свои, самодельные.
Итак, работающий кусок default.vrd
<service name="testservis"
rootUrl="testservis"
enable="true"
reuseSessions="autouse"
sessionMaxAge="30"
poolSize="10"
poolTimeout="5">
<accessTokenAuthentication>
<accessTokenRecepientName>testservis</accessTokenRecepientNa me>
<issuers>
<issuer name="ssl" authenticationClaimName="sub" authenticationUserPropertyName="name" keyInformation="0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw="/>
</issuers>
</accessTokenAuthentication>
</service> ПоказатьЧтобы сгенерировать токен под ЭТУ настройку, используется вот такой код 1С
А
АлгоритмПодписи = АлгоритмПодписиТокенаДоступа.HS256;
ТокенДоступа = Новый ТокенДоступа;
ТокенДоступа.Заголовки.Вставить("alg", Строка(АлгоритмПодписи));
ТокенДоступа.Эмитент = "ssl"; // прибито гвоздями как минимум в 8.3.21.1302
//ТокенДоступа.Получатели.Добавить("testservis"); // вот так указано в примерах в документации - работать не будет.
// нужно вот так
МассивПолучателей = Новый Массив;
МассивПолучателей.Добавить("testservis"); // имя http-сервиса из default.vrd
ТокенДоступа.Получатели = МассивПолучателей;
ТокенДоступа.КлючСопоставленияПользователя = "user1C"; // имя пользователя 1С, у которого должна стоять галочка "Аутентификация токеном доступа"
ТокенДоступа.ВремяСоздания = 1651838400; // в примерах от 1С ляп, токен создается в Москве на 3 часа в будущем и сразу не работает из-за использованнного способа получения timestamp
ТокенДоступа.ВремяЖизни = 2592000;
ТокенДоступа.Идентификатор = Новый УникальныйИдентификатор;
ТокенДоступа.Подписать(АлгоритмПодписи, "0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw="); // ключик из default.vrd
ТекстТокена = Строка(ТокенДоступа); // получим токен строкой
Сообщить(ТекстТокена);
Показать
Для окончательной ясности приложите, пожалуйста, раскодированный из Base64 токен, сгенерированный в Вашем примере.
(11)
А как вы решили дату создания?
Допустим я создаю по GMT + 6 в 12:00 и время жизни ставлю 3600 (1 час). Все хорошо, у местных будет час времени на истечение токена.
Теперь у меня есть пользователи которые находятся в GMT + 5, получается для них токен действует 2 часа?
В инете писали чтобы формировал время создания по UTC что не совсем мне понятно, в любом случае если UTC это всемирное координированное время а GMT это среднее время по Гринвичу то в любом случае будет разница во времени жизни токена?
Вроде в токене просто секунды, нет информации что там токен создали по GMT + 6...
Как вы это решили подскажите пожалуйста? ТекущаяУниверсальнаяДата?
А как вы решили дату создания?
Допустим я создаю по GMT + 6 в 12:00 и время жизни ставлю 3600 (1 час). Все хорошо, у местных будет час времени на истечение токена.
Теперь у меня есть пользователи которые находятся в GMT + 5, получается для них токен действует 2 часа?
В инете писали чтобы формировал время создания по UTC что не совсем мне понятно, в любом случае если UTC это всемирное координированное время а GMT это среднее время по Гринвичу то в любом случае будет разница во времени жизни токена?
Вроде в токене просто секунды, нет информации что там токен создали по GMT + 6...
Как вы это решили подскажите пожалуйста? ТекущаяУниверсальнаяДата?
(11)
Такая конструкция в jwt.io показывает ошибку даты: "Invalid date"
Значение "iat" должно быть без кавычек, т.е. числового типа.
Самое интересное, что 1С в любом случае создает эти поля строкового типа, но затем при обращении сам же выдает ошибку, что "iat" некорректный. Т.е. при создании токена не следует формату полей дат, а при проверке следует. Таким образом, токены, созданные в 1С, не проходят проверку корректности в jwt.io и следовательно не подходят для работы.
Кто-то смог победить такое?
Такая конструкция в jwt.io показывает ошибку даты: "Invalid date"
Значение "iat" должно быть без кавычек, т.е. числового типа.
Самое интересное, что 1С в любом случае создает эти поля строкового типа, но затем при обращении сам же выдает ошибку, что "iat" некорректный. Т.е. при создании токена не следует формату полей дат, а при проверке следует. Таким образом, токены, созданные в 1С, не проходят проверку корректности в jwt.io и следовательно не подходят для работы.
Кто-то смог победить такое?
Добрый день. А по web-сервисам есть примеры использования JWT? Не могу понять куда его (токен) передать чтобы произошла авторизация.
(24)
(16) Пробую сделать авторизацию токеном для бесшовки в Документообороте 2.1. Столкнулся с тем, что для WSПрокси создаваемого на основании WSОпределения, уже на этапе создания WSОпределения не проходит авторизация. Пришлось там тоже прописывать токен
НовоеМестоположениеWSDL = МестоположениеWSDL + "ws/dm.1cws?wsdl&AccessToken=" + ТокенДоступа;
Определения = Новый WSОпределения(НовоеМестоположениеWSDL,
ИмяПользователя,
Пароль,
ИнтернетПрокси,
Таймаут,
ЗащищенноеСоединение,
ПоддерживаетсяАутентификацияОС И ИспользуетсяАутентификацияОС);
И для WSПрокси тоже дублировать авторизацию токеном
Прокси = Новый WSПрокси(Определения,
"http://www.1c.ru/dm",
"DMService",
"DMServiceSoap",
ИнтернетПрокси,
Таймаут,
ЗащищенноеСоединение,
НовоеМестоположениеWSDL,
ПоддерживаетсяАутентификацияОС И ИспользуетсяАутентификацияОС);
Но при вызове выходит ошибка
Запрос = СоздатьОбъект(Прокси, "DMGetVersionRequest");
Ответ = Прокси.execute(Запрос);
Ошибка при вызове метода контекста (execute)
{ОбщийМодуль.ИнтеграцияС1СДокументооборот.Модуль(5008)}:Ответ = Прокси.execute(Запрос);
{ОбщийМодуль.ИнтеграцияС1СДокументооборот.Модуль(244)}:ВерсияСервиса = ПолучитьВерсиюВызовомСервиса(ИмяПользователя, Пароль, ИспользуетсяАутентификацияОС);
{ОбщийМодуль.ИнтеграцияС1СДокументооборотВызовСервера.Модуль(551)}:ИнтеграцияС1СДокументооборот.УстановитьВерсиюСервиса(Неопределено,
{Обработка.ИнтеграцияС1СДокументооборот.Форма.АвторизацияВ1СДокументооборот.Форма(91)}:ИнтеграцияС1СДокументооборотВызовСервера.УстановитьВерсиюСервисаВПараметрыСеанса();
по причине:
При вызове веб-сервиса произошла ошибка. Ошибка вызова операции сервиса: {}:DMService:execute()
по причине:
Ошибка разбора SOAP сообщения: неверная версия сообщения.
(16) Пробую сделать авторизацию токеном для бесшовки в Документообороте 2.1. Столкнулся с тем, что для WSПрокси создаваемого на основании WSОпределения, уже на этапе создания WSОпределения не проходит авторизация. Пришлось там тоже прописывать токен
НовоеМестоположениеWSDL = МестоположениеWSDL + "ws/dm.1cws?wsdl&AccessToken=" + ТокенДоступа;
Определения = Новый WSОпределения(НовоеМестоположениеWSDL,
ИмяПользователя,
Пароль,
ИнтернетПрокси,
Таймаут,
ЗащищенноеСоединение,
ПоддерживаетсяАутентификацияОС И ИспользуетсяАутентификацияОС);
И для WSПрокси тоже дублировать авторизацию токеном
Прокси = Новый WSПрокси(Определения,
"http://www.1c.ru/dm",
"DMService",
"DMServiceSoap",
ИнтернетПрокси,
Таймаут,
ЗащищенноеСоединение,
НовоеМестоположениеWSDL,
ПоддерживаетсяАутентификацияОС И ИспользуетсяАутентификацияОС);
Но при вызове выходит ошибка
Запрос = СоздатьОбъект(Прокси, "DMGetVersionRequest");
Ответ = Прокси.execute(Запрос);
Ошибка при вызове метода контекста (execute)
{ОбщийМодуль.ИнтеграцияС1СДокументооборот.Модуль(5008)}:Ответ = Прокси.execute(Запрос);
{ОбщийМодуль.ИнтеграцияС1СДокументооборот.Модуль(244)}:ВерсияСервиса = ПолучитьВерсиюВызовомСервиса(ИмяПользователя, Пароль, ИспользуетсяАутентификацияОС);
{ОбщийМодуль.ИнтеграцияС1СДокументооборотВызовСервера.Модуль(551)}:ИнтеграцияС1СДокументооборот.УстановитьВерсиюСервиса(Неопределено,
{Обработка.ИнтеграцияС1СДокументооборот.Форма.АвторизацияВ1СДокументооборот.Форма(91)}:ИнтеграцияС1СДокументооборотВызовСервера.УстановитьВерсиюСервисаВПараметрыСеанса();
по причине:
При вызове веб-сервиса произошла ошибка. Ошибка вызова операции сервиса: {}:DMService:execute()
по причине:
Ошибка разбора SOAP сообщения: неверная версия сообщения.
(24)
(25)
Разобрался.
Вместо этого для WSПрокси нужно было указывать местоположение без wsdl
НовоеМестоположениеWSDL = МестоположениеWSDL + "ws/dm.1cws?AccessToken=" + ТокенДоступа;
Прокси = Новый WSПрокси(Определения,
"http://www.1c.ru/dm",
"DMService",
"DMServiceSoap",
ИнтернетПрокси,
ТаймаутСервиса(),
ЗащищенноеСоединение,
НовоеМестоположениеWSDL,
ИспользуетсяАутентификацияОС);
(16) Всё верно указал. Это моя невнимательность.
(25)
НовоеМестоположениеWSDL = МестоположениеWSDL + "ws/dm.1cws?wsdl&AccessToken=" + ТокенДоступа;
Разобрался.
Вместо этого для WSПрокси нужно было указывать местоположение без wsdl
НовоеМестоположениеWSDL = МестоположениеWSDL + "ws/dm.1cws?AccessToken=" + ТокенДоступа;
Прокси = Новый WSПрокси(Определения,
"http://www.1c.ru/dm",
"DMService",
"DMServiceSoap",
ИнтернетПрокси,
ТаймаутСервиса(),
ЗащищенноеСоединение,
НовоеМестоположениеWSDL,
ИспользуетсяАутентификацияОС);
(16) Всё верно указал. Это моя невнимательность.
Доброго дня подскажите пожалуйста, все делаю как у вас, но у меня сервис выдает вот такое, уже голову сломал, что может быть не так:
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/redirect.php?url=aHR0cDovL2xvY2FsaG9zdC9EZW1vVHJkU2VydmljZS9lMWNzeXMvdnJzY29yZS9leGNlcHRpb24ueHNsdD9zeXN2ZXI9OC4zLjIxLjEzMDI="?><exception xmlns="http://v8.1c.ru/8.2/virtual-resource-system" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Exception" clsid="580392e6-ba49-4280-ac67-fcd6f2180121" reason="-16"><descr xmlns="http://v8.1c.ru/8.1/data/core">Claim not foundaud</descr><category xmlns="http://v8.1c.ru/8.1/data/core">0000000000000000000000</category><creationStack xmlns="http://v8.1c.ru/8.1/data/core">core83.dll:0x0000000000085998 vrsbase.dll:0x000000000009B229 vrsbase.dll:0x00000000002B8AC6 VCRUNTIME140.dll:0x0000000000000000 VCRUNTIME140.dll:0x0000000000000000 ntdll.dll:0x0000000000000000 vrsbase.dll:0x00000000000F2851 vrsbase.dll:0x000000000009DA68 vrsbase.dll:0x000000000009CF76 vrsbase.dll:0x000000000009C650 vrsbase.dll:0x00000000000D793C vrsbase.dll:0x00000000000DCC13 vrsbase.dll:0x00000000000995DE vrsbase.dll:0x00000000000E4F83 vrsbase.dll:0x00000000000DA59F vrsbase.dll:0x00000000000E51E5 vrsbase.dll:0x00000000000E589D core83.dll:0x00000000002B166B core83.dll:0x00000000002B169C core83.dll:0x000000000017576E ucrtbase.DLL:0x0000000000000000 kernel32.dll:0x0000000000000000 ntdll.dll:0x0000000000000000 </creationStack></exception>
Токен проверяю на все нормально разбирает.
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/redirect.php?url=aHR0cDovL2xvY2FsaG9zdC9EZW1vVHJkU2VydmljZS9lMWNzeXMvdnJzY29yZS9leGNlcHRpb24ueHNsdD9zeXN2ZXI9OC4zLjIxLjEzMDI="?><exception xmlns="http://v8.1c.ru/8.2/virtual-resource-system" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Exception" clsid="580392e6-ba49-4280-ac67-fcd6f2180121" reason="-16"><descr xmlns="http://v8.1c.ru/8.1/data/core">Claim not foundaud</descr><category xmlns="http://v8.1c.ru/8.1/data/core">0000000000000000000000</category><creationStack
Токен проверяю на все нормально разбирает.
(23) Добавляя массив в ТокенДоступа.Получатели вы на уровне платформы заполняете значение для ключа "aud" в ПолезнаяНагрузка. Главное учесть, что имя http-сервиса (значение атрибута "name" элемента "service") может отличаться от значения вложенного элемента "accessTokenRecepientName".
(28) см сообщение (9)
ТокенДоступа.Подписать(АлгоритмПодписи, "0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw="); // ключик из default.vrd
вот этот ключик должен быть одинаковый с keyInformation в default.vrd
сгенерировать его нужно самому, любой секретный текст кодируется в base64 - и ключ готов
ТокенДоступа.Подписать(АлгоритмПодписи, "0KHQuNC60YDQtdGC0L3Ri9C5INC60LvRjtGH0Yw="); // ключик из default.vrd
вот этот ключик должен быть одинаковый с keyInformation в default.vrd
сгенерировать его нужно самому, любой секретный текст кодируется в base64 - и ключ готов
В раздел payload токена можно записать и другие произвольные значения. Платформа это позволяет.
Но я не нашел в платформе возможности прочитать данные из токена, по которому была выполнена авторизация.
Плохо искал или действительно их нет и нужно использовать 1c-jwt?
Но я не нашел в платформе возможности прочитать данные из токена, по которому была выполнена авторизация.
Плохо искал или действительно их нет и нужно использовать 1c-jwt?
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот
