СоздатьСтруктуруWSSecurityДляSOAPсообщения

https://ps.tmpc.ru/282e28e7cfc8

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
&НаКлиентеНаСервереБезКонтекста
Функция СоздатьСтруктуруWSSecurityДляSOAPсообщения2(СтрокаXML) Экспорт
	
	// Построим DOM из строки XML.
	ЧтениеXML_ = Новый ЧтениеXML;
	ЧтениеXML_.УстановитьСтроку(СтрокаXML);
	ПостроительDOM_ = Новый ПостроительDOM;
	ДокументDOM_ = ПостроительDOM_.Прочитать(ЧтениеXML_);
	
	// Корневой элемент - это SOAP-ENV:Envelope.
	КорневойЭлемент_ = ДокументDOM_.ЭлементДокумента;
	
	// Пространства имен SOAP версии 1.1 и 1.2 различаются,
	// поэтому извлечем нужное пространство имен из корневого тега.
	xmlnsSOAP_ENV_ = КорневойЭлемент_.URIПространстваИмен;
	
	// Добавим в конверт тег SOAP-ENV:Header, если его не было.
	Если Не "Header" = КорневойЭлемент_.ПервыйДочерний.ЛокальноеИмя Тогда
		Header_ = ДокументDOM_.СоздатьЭлемент(xmlnsSOAP_ENV_, "Header");
		КорневойЭлемент_.ВставитьПеред(Header_, КорневойЭлемент_.ПервыйДочерний);
	КонецЕсли;
	
	// Добавляем атрибут wsu:Id в тег <SOAP-ENV:Body>.
	xmlns_wsu_ = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
	wsuId_ = "uuid:" + Строка(Новый УникальныйИдентификатор);
	// За следующие строки кода спасибо автору топика. Сам не смог догадаться.
	Атрибут_wsuId_ = ДокументDOM_.СоздатьАтрибут(xmlns_wsu_, "wsu:Id");
	Атрибут_wsuId_.Значение = wsuId_;
	// ПоследнийДочерний - это тег <SOAP-ENV:Body>.
	КорневойЭлемент_.ПоследнийДочерний.Атрибуты.УстановитьИменованныйЭлемент(Атрибут_wsuId_);
	
	// Тег <wsse:Security> сформируем из строкового шаблона. Так гораздо более читабельно,
	// чем работа с DOM.
	// Параметрами шаблона выступают два атрибута wsu:Id и пространство имен SOAP-ENV.
	Шаблон_wsseSecurity_ = 
		"<wsse:Security
		|		xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""
		|		xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd""
		|		xmlns:SOAP-ENV=""%3""
		|		SOAP-ENV:mustUnderstand=""1""
		|		SOAP-ENV:actor=""http://smev.gosuslugi.ru/actors/smev"">
		|	<wsse:BinarySecurityToken
		|			wsu:Id=""%1""
		|			ValueType=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3""
		|			EncodingType=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"">#Certificate_ENCODE_BASE64</wsse:BinarySecurityToken>
		|	<ds:Signature xmlns:ds=""http://www.w3.org/2000/09/xmldsig#"">
		|		<ds:SignedInfo>
		|			<ds:CanonicalizationMethod Algorithm=""http://www.w3.org/2001/10/xml-exc-c14n#""/>
		|			<ds:SignatureMethod Algorithm=""http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411""/>
		|			<ds:Reference URI=""#%2"">
		|				<ds:Transforms>
		|					<ds:Transform Algorithm=""http://www.w3.org/2001/10/xml-exc-c14n#""/>
		|				</ds:Transforms>
		|				<ds:DigestMethod Algorithm=""http://www.w3.org/2001/04/xmldsig-more#gostr3411""/>
		|				<ds:DigestValue/>
		|			</ds:Reference>
		|		</ds:SignedInfo>
		|		<ds:SignatureValue/>
		|		<ds:KeyInfo>
		|			<wsse:SecurityTokenReference>
		|				<wsse:Reference
		|						ValueType=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3""
		|						URI=""#%1""/>
		|			</wsse:SecurityTokenReference>
		|		</ds:KeyInfo>
		|	</ds:Signature>
		|</wsse:Security>"
	;
	Тег_wsseSecurity_ = СтрШаблон(
		Шаблон_wsseSecurity_,
		"uuid:" + Строка(Новый УникальныйИдентификатор),
		wsuId_,
		xmlnsSOAP_ENV_
	);
	
	// Полученную строку с тегом <wsse:Security> прочитаем в другой DOM.
	ЧтениеXML_ = Новый ЧтениеXML;
	ЧтениеXML_.УстановитьСтроку(Тег_wsseSecurity_);
	ПостроительDOM_ = Новый ПостроительDOM;
	ДокументDOM_wsseSecurity_ = ПостроительDOM_.Прочитать(ЧтениеXML_);
	
	// Теперь перенесем тег <wsse:Security> из одного документа DOM в другой.
	wsseSecurity_ = ДокументDOM_.ИмпортироватьУзел(ДокументDOM_wsseSecurity_.ЭлементДокумента, Истина);
	// ПервыйДочерний - это <SOAP-ENV:Header>. Добавим в него тег <wsse:Security>.
	КорневойЭлемент_.ПервыйДочерний.ДобавитьДочерний(wsseSecurity_);
	
	// Осталось только записать DOM в строку.
	ЗаписьXML_ = Новый ЗаписьXML;
	ЗаписьXML_.УстановитьСтроку("UTF-8");
	ЗаписьDOM_ = Новый ЗаписьDOM;
	ЗаписьDOM_.КонфигурацияDOM.УстановитьПараметр("xml-declaration", Истина);
	ЗаписьDOM_.КонфигурацияDOM.УстановитьПараметр("discard-default-content", Истина);
	ЗаписьDOM_.Записать(ДокументDOM_, ЗаписьXML_);
	
	СформированныйДокумент_ = ЗаписьXML_.Закрыть();
	
	Возврат СформированныйДокумент_;
	
КонецФункции