Можно ли использовать методы web сервиса http запросом?

1. user646807_kazako.a911 13 25.10.23 09:11 Сейчас в теме
Добрый день!

Мне поставили задачу интеграции сайта ЕФРСБ и 1С.
В сервисе ЕФРСБ есть ws-ссылка, после добавления которой в дереве метаданных появилась структура сервиса, дополнительно есть описание пакетов.

При выполнении любого метода данного сервиса прилетает ошибка 401, не авторизован. Пример кода с результатом ошибка 401:

 текURI						 = "http://tempuri.org/";
    текНаименованиеВебСервиса	 = "MessageService";
    текНаименованиеПорта		 = "BasicHttpBinding_IMessageService";
    
    // Соединение
	текСервис	 = WSСсылки.ТестовыйЕФРСБ.СоздатьWSПрокси(текURI, текНаименованиеВебСервиса, текНаименованиеПорта,,,Новый ЗащищенноеСоединениеOpenSSL);
	текСервис.Пользователь	 = Логин;
	текСервис.Пароль		 = Пароль;
	
	НачалоПериода	 = "2023-10-01T00:00:00";
	КонецПериода	 = "2023-10-20T00:00:00";
	ОтветОтСервера = текСервис.GetMessageIds(НачалоПериода, КонецПериода);
Показать


В описании сервиса нашел что используется «Digest access authentication», гугл не дал результатов как в 1С можно пройти Digest-аутентификацию используя методы web-сервиса. В комментариях к теме https://infostart.ru/1c/tools/835540/, нашел пример, как можно пройти Digest-аутентификацию используя методы http-запроса. Немного переделав код смог авторизоваться на сервисе, запрос на главную страницу сервиса, в ответе получил код 200, вроде все ок.

Адрес сервиса "services.fedresurs.ru", адрес страницы "/Bankruptcy/MessageServiceDemo/WebService.svc", ответ код 200.

Вопрос, можно ли использовать методы web-сервиса описанные в ws-ссылке в http-запросах? Если можно как их формировать?
Например если взять методы, описанные в ws-сслыке, имя сервиса "MessageService", имя порта "BasicHttpBinding_IMessageService". Пытался добавить эти данные в адрес страницы.

Адрес сервиса "services.fedresurs.ru", адрес страницы "/Bankruptcy/MessageServiceDemo/WebService.svc/MessageService/BasicHttpBinding_IMessageService", ответ код 415.
"/Bankruptcy/MessageServiceDemo/WebService/MessageService/Ba­sicHttpBinding_IMessageService", ответ код 404.

Пример кода с авторизацией с помощью http-запроса, ответ код 200
&НаКлиенте
Процедура ТестЕФРСБ(Команда)
	
	ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
	
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-Type", "application/json");
	Заголовки.Вставить("accept", "application/json");  
		
	ИмяМетода = "GET";
		
	АдресСервиса	 = "services.fedresurs.ru";
	АдресСтраницы	 = "/Bankruptcy/MessageServiceDemo/WebService.svc";
	
	HTTPСоединение	 = Новый HTTPСоединение(АдресСервиса,,,,,,ЗащищенноеСоединение);
  	HTTPЗапрос		 = Новый HTTPЗапрос(АдресСтраницы, Заголовки);
		
	Попытка
		HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
	Исключение
		// обработка исключения
	КонецПопытки; 	
	
	Если HTTPОтвет.КодСостояния = 401 Тогда
		ЗаголовокАвторизации = HTTPОтвет.Заголовки.Получить("WWW-Authenticate");
		Если НЕ ЗаголовокАвторизации = Неопределено Тогда
			
			ПараметрыАутентификации = Новый Структура;
			ЗаголовокАвторизации = СтрЗаменить(ЗаголовокАвторизации,"Digest","");
			МассивПараметров = СтрРазделить(ЗаголовокАвторизации,",");
			Для Каждого ТекПараметрСтрокой Из МассивПараметров Цикл
				
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "nonce");
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "opaque");
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "stale");
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "algorithm");
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "qop");
				ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, "realm");
				
			КонецЦикла;
			
			nc = 1;
			ПараметрыАутентификации.Вставить("uri", АдресСтраницы);
			ПараметрыАутентификации.Вставить("nc", Формат(nc,"ЧЦ=8; ЧДЦ=; ЧВН=; ЧГ=0"));
			ПараметрыАутентификации.Вставить("cnonce", НРег(СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "")));
						
			Если ПараметрыАутентификации.Свойство("nonce") И ПараметрыАутентификации.Свойство("opaque") И ПараметрыАутентификации.Свойство("stale") 
					И ПараметрыАутентификации.Свойство("algorithm") И ПараметрыАутентификации.Свойство("qop") И ПараметрыАутентификации.Свойство("realm") Тогда
					
					HA1 = ПолучитьХеш(Логин+":"+ПараметрыАутентификации.realm+":"+Пароль);    
            		HA1 = ХексВСтроку(HA1);
		            
            		HA2 = ПолучитьХеш(ВРег(ИмяМетода)+":"+АдресСтраницы);
            		HA2 = ХексВСтроку(HA2);
			
					Если ПараметрыАутентификации.qop = "auth" Тогда
                		Response  = ПолучитьХеш(HA1+":"+ПараметрыАутентификации.nonce+":"+ПараметрыАутентификации.nc+":"+ПараметрыАутентификации.cnonce+":"+ПараметрыАутентификации.qop+":"+HA2);    
            		Иначе
                		Response  = ПолучитьХеш(HA1+":"+ПараметрыАутентификации.nonce+":"+HA2);
            		КонецЕсли;
            		Response = ХексВСтроку(Response);
					ПараметрыАутентификации.Вставить("response", Response);
					
					Заголовки = Новый Соответствие();
					Заголовки.Вставить("Content-Type", "application/json");
					Заголовки.Вставить("accept", "application/json");
										
					DigestЗапрос = "Digest username="""+Логин+""", realm="""+ПараметрыАутентификации.realm+""", nonce="""+ПараметрыАутентификации.nonce;
            		DigestЗапрос = DigestЗапрос+""", uri="""+ПараметрыАутентификации.uri+""", qop="""+ПараметрыАутентификации.qop+""", nc="""+ПараметрыАутентификации.nc;
            		DigestЗапрос = DigestЗапрос+""", cnonce="""+ПараметрыАутентификации.cnonce+""", response="""+ПараметрыАутентификации.response+""", opaque="""+ПараметрыАутентификации.opaque+"""";
					Заголовки.Вставить("Authorization", DigestЗапрос);
					
					ЗаполнитьЗначенияСвойств(Заголовки, ПараметрыАутентификации);
					
					HTTPЗапрос		 = Новый HTTPЗапрос(АдресСтраницы, Заголовки);
	
					Попытка
						HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
					Исключение
						// обработка исключения
					КонецПопытки; 
					
			КонецЕсли;
				
		КонецЕсли;
			
	КонецЕсли;
	    
		
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьХеш(Текст)
	
    ОбъектХеш = Новый ХешированиеДанных(ХешФункция.MD5);
    ОбъектХеш.Добавить(Текст);
    
    Возврат ОбъектХеш.ХешСумма;
	
КонецФункции

&НаКлиенте
Функция ХексВСтроку(Текст)
    
    Возврат НРег(СтрЗаменить(Строка(Текст), " ", ""));
    
КонецФункции

&НаКлиенте
Процедура ДобавитьЗначениеИзСтрокиПараметраАутентификации(ПараметрыАутентификации, ТекПараметрСтрокой, ИмяПараметра)
	
	Если НЕ СтрНайти(ТекПараметрСтрокой,ИмяПараметра) = 0 Тогда
		ПараметрыАутентификации.Вставить(ИмяПараметра, СтрЗаменить(СтрЗаменить(СокрЛП(ТекПараметрСтрокой), ИмяПараметра + "=", ""),"""",""));
	КонецЕсли;	
	
КонецПроцедуры
Показать


Может ссылки есть на какие-то материалы, я чувствую что вообще не рублю в этих сервисах. Скорее всего по рабочему примеру сделал бы, но нашел только один источник на инфостарте, по размещению данных на ЕФРСБ, стоит 10 стартмани, низкий рейтинг и старая публикация.

ЕФРСБ на все вопросы посылают, программа svcutil с их примера при загрузке ws-ссылки выдает ошибку, нашел статью по мониторингу пакетов https://its.1c.ru/db/metod8dev/content/1939/hdoc, установил Wireshark, думал подсмотреть что отправляет запрос к web-сервису из кода 1С, пока не разобрался. Хелп!

ws-ссылка https://services.fedresurs.ru/Bankruptcy/MessageServiceDemo/WebService.svc?wsdl
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. user646807_kazako.a911 13 03.11.23 09:46 Сейчас в теме
Ответ: можно. https://infostart.ru/1c/articles/516653/
Посмотрел, что Boomerang отправлял в заголовках и теле запроса, сделал так же и взлетело. Шайтанмашина =)
4. user856012 13 03.11.23 10:32 Сейчас в теме
(2)
Шайтанмашина =)
Наверное, помогло оформление ветки тегами в стиле:
Прикрепленные файлы:
user646807_kazako.a911; +1 Ответить
3. starik-2005 3039 03.11.23 10:13 Сейчас в теме
В документации сервиса ща описана вторая версия, там нет WS - там HTTP-сервисы. И XML туда посылается base64-строкой с помощью определенных методов. Я про веб-сервисы даже описания там не нашел.
user646807_kazako.a911; +1 Ответить
5. user646807_kazako.a911 13 03.11.23 13:21 Сейчас в теме
(4)
А как правильно делать?

Нужно сформировать тело запроса, например:

<x:Envelope
xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tem="http://tempuri.org/">
<x:Header/>
<x:Body>
<GetMessageIds xmlns="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<startDate>2023-11-01T00:00:00</startDate>
	<endDate>2023-11-03T00:00:00</endDate>
</GetMessageIds>
</x:Body>
</x:Envelope>
Показать


То что в BODY формирую чз XDTO-пакет, а остальное, теги Header, Body добавляю текстом

ТелоЗапроса = "<x:Envelope
    |xmlns:x=""http://schemas.xmlsoap.org/soap/envelope/""
    |xmlns:tem=""http://tempuri.org/"">
    |<x:Header/>
    |<x:Body>" + СформироватьТекстXML("GetMessageIds",СтруктураПараметров) + "
	|</x:Body>
	|</x:Envelope>";
Показать
6. user646807_kazako.a911 13 03.11.23 15:06 Сейчас в теме
(3)
У них есть для сервиса ЕФРСБ wsdsl, когда добавил ws-ссылку в 1С, добавилось без ошибок.
Из этого сделал вывод, что можно использовать механизмы web-сервиса.

Методы использовать получилось с помощью http, но фабрика XDTO из сервиса не полностью раскладывает пакет в XDTO

Получаю фабрику
текURI						 = "http://tempuri.org/";
	текНаименованиеВебСервиса	 = "MessageService";
	текНаименованиеПорта		 = "BasicHttpBinding_IMessageService";
	текСервис					 = WSСсылки.ТестовыйЕФРСБ.СоздатьWSПрокси(текURI, текНаименованиеВебСервиса,  текНаименованиеПорта,,,Новый ЗащищенноеСоединениеOpenSSL);
	ТекФабрика					 = ТекСервис.ФабрикаXDTO;
	
	Возврат ТекФабрика;
Показать


Прилетает ответ от сервера
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetMessageContentResponse xmlns="http://tempuri.org/"><GetMessageContentResult><MessageData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>1669982</Id>
  <Number>1669982</Number>
  <Publisher xsi:type="Publisher.ForeignSystem.v2">
    <Name>Включение сведений с использованием программно-аппаратного комплекса ЕФРСБ</Name>
  </Publisher>
  <MessageInfo MessageType="CompletionOfExtrajudicialBankruptcy">
    <CompletionOfExtrajudicialBankruptcy>
      <Text>Процедура внесудебного банкротства завершена.</Text>
      <StartOfExtrajudicialBankruptcyMessageNumber>1667116</StartO­fExtrajudicialBankruptcyMessageNumber>
    </CompletionOfExtrajudicialBankruptcy>
  </MessageInfo>
  <Bankrupt xsi:type="Bankrupt.Person.v2">
    <Category>
      <Code>SimplePerson</Code>
      <Description>Физическое лицо</Description>
    </Category>
    <Fio>
      <LastName>Кощеева</LastName>
      <FirstName>Наталья</FirstName>
      <MiddleName>Рауэльевна</MiddleName>
    </Fio>
    <Inn>662703502919</Inn>
    <Snils>02253405707</Snils>
    <Address>Свердловская область, г. Ревда, ул. Азина, дом 60,кв 18</Address>
    <Birthdate>08.09.1971</Birthdate>
    <Birthplace>гор. Ревда Свердловской обл.</Birthplace>
    <FioHistory>
      <Fio>
        <LastName>-</LastName>
        <FirstName>Шакирова</FirstName>
        <MiddleName>-</MiddleName>
      </Fio>
    </FioHistory>
  </Bankrupt>
  <PublishDate>2023-11-01T15:38:42.08</PublishDate>
  <BankruptId>140133</BankruptId>
  <MessageGUID>B52228B659D740FE8299A9006C523528</MessageGUID>
</MessageData></GetMessageContentResult></GetMessageContentR­esponse></s:Body></s:Envelope>
Показать


Читаю ответ с помощью фабрики XDTO
ТекФабрика = ПолучитьФабрикуXDTOИзСервиса();
	
	ПозицияПервогоСимвола	 = СтрНайти(ТекстОтвета,"<" + ТипДанных);
	ПозицияПоследнегоСимвола = СтрНайти(ТекстОтвета,"</" + ТипДанных);
	ТелоHTTPОтвета = Сред(ТекстОтвета,ПозицияПервогоСимвола,ПозицияПоследнегоСимвола + СтрДлина(ТипДанных) + 3 - ПозицияПервогоСимвола);
	
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(ТелоHTTPОтвета);
	XDTOПакет = ТекФабрика.ПрочитатьXML(ЧтениеXML);
Показать


В итоге получаю пакет XDTO в котором в реквизит "GetMessageContentResult" вложен тег с XML. ???
<MessageData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>1669982</Id>
  <Number>1669982</Number>
  <Publisher xsi:type="Publisher.ForeignSystem.v2">
    <Name>Включение сведений с использованием программно-аппаратного комплекса ЕФРСБ</Name>
  </Publisher>
  <MessageInfo MessageType="CompletionOfExtrajudicialBankruptcy">
    <CompletionOfExtrajudicialBankruptcy>
      <Text>Процедура внесудебного банкротства завершена.</Text>
      <StartOfExtrajudicialBankruptcyMessageNumber>1667116</StartO­fExtrajudicialBankruptcyMessageNumber>
    </CompletionOfExtrajudicialBankruptcy>
  </MessageInfo>
  <Bankrupt xsi:type="Bankrupt.Person.v2">
    <Category>
      
Код
SimplePerson
Показать полностью
<Description>Физическое лицо</Description> </Category> <Fio> <LastName>Кощеева</LastName> <FirstName>Наталья</FirstName> <MiddleName>Рауэльевна</MiddleName> </Fio> <Inn>662703502919</Inn> <Snils>02253405707</Snils> <Address>Свердловская область, г. Ревда, ул. Азина, дом 60,кв 18</Address> <Birthdate>08.09.1971</Birthdate> <Birthplace>гор. Ревда Свердловской обл.</Birthplace> <FioHistory> <Fio> <LastName>-</LastName> <FirstName>Шакирова</FirstName> <MiddleName>-</MiddleName> </Fio> </FioHistory> </Bankrupt> <PublishDate>2023-11-01T15:38:42.08</PublishDate> <BankruptId>140133</BankruptId> <MessageGUID>B52228B659D740FE8299A9006C523528</MessageGUID> </MessageData>
Показать
Прикрепленные файлы:
7. user646807_kazako.a911 13 03.11.23 15:16 Сейчас в теме
Понял. Скорее всего не читает так как нет описания этого вложенного типа (GetMessageContentResult) в описании пакетов сервиса.

Интересно почему...
Прикрепленные файлы:
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот