Добрый день!
Подскажите, пытаюсь путем http api получать какую-либо информацию из лк Лк ПРСД
Проблема возникает уже на этапе подключения (ранее с api не сталкивался, первая попытка).
Из информации есть следующее:
Взаимодействие с системой Личный кабинет ПРСД осуществляется по протоколу HTTPS. Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД. Цифровые подписи передаются через HTTP заголовок X-FRSD-Authentication
Для всех методов в заголовке X-FRSD-Authentication необходимо передать подпись url запроса в base64 формате. Т.е. тебе надо строку закодировать в base64 и поместить в заголовок. Вот хороший пример как закодировать - https://forum.infostart.ru/forum9/topic136888/#message2165435
Как закодируешь то попробуй что то получить от сервиса, например
Получение списка документов.
GET /doc-list?od=${date}
Возвращает список документов в xml формате.
Пример запроса ниже, "результат" - "расшифрованный" ответ сервиса. Если где то накосячил, коллеги поправьте.
Заголовки = Новый Соответствие;
Заголовки.Вставить("X-FRSD-Authentication", ЗакодированнаяСтрокаURLвBase64);
СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-01-01", Заголовки);
HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);
КодОтвета = HTTPОтвет.КодСостояния;
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Ответ);
Результат = ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
ДвоичныеДанныеСертификата = Сертификат.ДанныеСертификата.Получить();
ИмяФайлаДанныеСертификата = ПолучитьимяВременногоФайла("cer");
ДвоичныеДанныеСертификата.Записать(ИмяФайлаДанныеСертификата);
ЗакодированнаяСтрокаURLвBase64 = Base64Строка(ДвоичныеДанныеСертификата);
Заголовки = Новый Соответствие;
Заголовки.Вставить("X-FRSD-Authentication", ЗакодированнаяСтрокаURLвBase64);
СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-01-01", Заголовки);
HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);
КодОтвета = HTTPОтвет.КодСостояния;
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
Сообщить (КодОтвета);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Ответ);
Результат = ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
Показать
В ответ село:
<!DO CTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HT ML><HEAD><TITLE>Bad Request</TITLE>
<MET A HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>
(5) На заголовок ругается, тебе в (4) говорил serg33rus, что двоичные данные в заголовок не вставить, а ты похоже именно это и помещаешь в соответствие "Заголовки".
С подписями не работал, подсказать не смогу.
Для всех методов в заголовке X-FRSD-Authentication необходимо передать подпись url запроса в base64 формате.
Т.е. как минимум подпись должна быть в base64. В заголовок воткнуть двоичные данные вообще невозможно.
Ну и вот эта фраза предусматривает передачу не сертификата, а подписи
Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД. Цифровые подписи передаются через HTTP заголовок X-FRSD-Authentication
(7) Нет. С этой системой не работал, но фраза "Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД"
Подразумевает, что передавать надо НЕ сертификат, а именно подпись. Т.е. сформировать подпись в ЛК при регистрации ключа. А потом именно эту подпись в base64 втыкать в header. Мне кажется что так.
В документации портала надо посмотреть внимательно как сформировать подпись.
Там же ясно написано: "передать подпись url запроса в base64 формате.", ты же это сам и приводил.
Берешь сертификат, грузишь в ЛК открытый ключ, у себя оставляешь закрытый. Когда тебе надо отправить запрос, берешь урл своего запроса, подписываешь своим закрытым ключем, полученное преобразуешь в base64 и вставляешь в заголовок. Отправляешь. На той стороне видят урл, видят подпись, проверяют ее при помощи открытого ключа, который ты загрузил в ЛК и убеждаются, что запрос отправлен действительно от тебя.
(9) На сайте у них размещен пример на c#, по отладчику пробежались работает он как вы и описали.
Создает пустой файл .dat, в него помещает строку"https://lk.frsd.ru/xapi/doc-list.xml?od=2024-05-23", этот файл подписывается закрытым ключом, и в итоге получается файл формата .dat.sgn. По итогу получаем xml файл со списком документов (ответ).
Но чз 1С так и не выходит авторизоваться. Последний вариант пробовали напрямую через файл, который получается в примере на c#, но тоже неверно, ошибка 401 ("Подпись запроса некорректна").
ФайлСертификата = Новый ДвоичныеДанные("\\fs\1CBackUp\1.sgn");
ФайлСертификатаBase64 = Base64Строка(ФайлСертификата);
ФайлСертификатаBase64 = СтрЗаменить(ФайлСертификатаBase64, Символы.ВК, "");
ФайлСертификатаBase64 = СтрЗаменить(ФайлСертификатаBase64, Символы.ПС, "");
Заголовки = Новый Соответствие;
Заголовки.Вставить("X-FRSD-Authentication", ФайлСертификатаBase64);
СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL());
HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-05-23", Заголовки);
HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);
КодОтвета = HTTPОтвет.КодСостояния;
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
Сообщить (Ответ);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Ответ);
Результат = ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
(11) Поменял, ну нет. Это запрос на получение списка документов, думаю допускается ">=" от даты.
Просмотрели, какая строка в base64 уходит из c#, и какая в 1С в переменной "ФайлСертификатаBase64" - строки идентичные.
Мб что-то с самим запросом неверно делаю..
(13) Спасибо, направили на верную мысль. В запросе 1С не было ".xml". Дописал, ответ получил)
Теперь нужно такой файл с подписью средствами 1С получить.
Подписать любой файл пробовал через МенеджерКриптографии - работает.
Можно будет создать текстовый файл, заполнить строкой запроса и подписать, но верный ли путь это будет? Или получится, что подгоняю под вариант из C# и есть другие пути?
Насколько я помню, метод Подписать менеджера криптографии возвращает двоичные данные подписи сразу, так что можно обойтись без файла. Посмотри в синтакс-помощнике.