Мне нужно создать wcf-клиент для вызова службы, с которой я не контролирую.
Мне дали wsdl и рабочий проект soapui.
Служба использует как имя пользователя/пароль, так и сертификат x509.
ОБНОВЛЕНИЕ
Теперь я понимаю, в чем проблема, но я до сих пор не знаю, какие шаги мне нужно предпринять, чтобы иметь возможность создать требуемое сообщение, поэтому любая помощь будет очень оценена.
Мне нужно подписать как UsernameToken, так и SecurityTokenReference.
Код, который я должен был создать, был удален из этого сообщения, поскольку его больше не используют. Я больше не добавляю SecurityBindingElement к привязке, вместо этого добавляю новое поведение, которое записывает элемент безопасности в заголовок.
Таким образом, безопасность node создается с нуля путем подклассификации класса SignedXml, добавления ссылок на подпись и последующего вызова ComputeSignature для создания Signature node в заголовке Security.
Вам нужно передать xml для входа в конструктор SignedXml, чтобы он работал. Это не проблема, проходящая в UsernameToken, и это выглядит правильно.
Проблема заключается в том, что SecurityTokenReference создается только тогда, когда вызывается ComputeSignature(), поэтому я не могу добавить ссылку подписи к этому элементу, поскольку она не существует в то время, когда она требуется (в пределах переопределенного GetIdElement метод SignedXml, который вызывается до ComputeSignature())
Код, который я использую для создания блока подписи для вставки в заголовок безопасности, выглядит следующим образом
string certificatePath = System.Windows.Forms.Application.StartupPath + "\\" + "Certs\\sign-and- enc.p12";
XmlDocument xd = new XmlDocument();
xd.LoadXml(xml);
// Set Certificate
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new X509Certificate2(certificatePath, "password");
MySignedXml signedXml = new MySignedXml(xd);
signedXml.SigningKey = cert.PrivateKey;
// Create a new KeyInfo object.
KeyInfo keyInfo = new KeyInfo();
keyInfo.Id = "";
MemoryStream keyInfoStream = new MemoryStream();
XmlWriter keyInfoWriter = XmlWriter.Create(keyInfoStream);
WSSecurityTokenSerializer.DefaultInstance.WriteKeyIdentifierClause(keyInfoWriter, new LocalIdKeyIdentifierClause("token_reference", typeof(X509SecurityToken)));
keyInfoWriter.Flush();
keyInfoStream.Position = 0;
XmlDocument keyInfoDocument = new XmlDocument();
keyInfoDocument.Load(keyInfoStream);
XmlAttribute attrib = keyInfoDocument.CreateAttribute("ValueType");
attrib.InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
keyInfoDocument.ChildNodes[1].ChildNodes[0].Attributes.Append(attrib);
KeyInfoNode keyInfoNode = new KeyInfoNode();
keyInfoNode.LoadXml(keyInfoDocument.DocumentElement);
keyInfo.AddClause(keyInfoNode);
// Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo;
// Need to use External Canonicalization method.
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#UsernameToken-1";
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
env.Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#";
reference.AddTransform(env);
reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1";
signedXml.AddReference(reference);
Reference reference2 = new Reference();
reference2.Uri = "#token_reference";
XmlDsigEnvelopedSignatureTransform env2 = new XmlDsigEnvelopedSignatureTransform();
env2.Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#";
reference2.AddTransform(env2);
reference2.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1";
signedXml.AddReference(reference2);
// Add the Signature Id
signedXml.Signature.Id = "MYSIG_ID";
// Compute the signature.
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
где переменная xml - это строка xml UsernameToken, а класс MySignedXml является подклассом SignedXml с переопределенным методом GetIdElement (чтобы попытаться найти и правильно устранить несуществующий SecurityTokenReference)
Я провел дни, исследуя и тестируя это сейчас, и, к сожалению, компания, предоставляющая услугу, не помогает, но мне нужно использовать их сервис.
Полное рабочее мыльное сообщение (проект soapUI)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:XXXXX">
<soapenv:Header xmlns:ebxml="http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/">
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-D05E596B5ABC341FEB13505090224061" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">MIIEnDCCBAWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBxDELMAkGA1UEBhMCTloxDTALBgNVBAgTBFdHVE4xEzARBgNVBAcTCldlbGxpbmd0b24xGDAWBgNVBAoTD0lSRFN0dWR5bGlua0IyQjEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxHjAcBgNVBAMTFWRldmNhLmIyYi5pcmQuZ292dC5uejEXMBUGA1UEKRMORGV2ZWxvcG1lbnQgQ0ExKDAmBgkqhkiG9w0BCQEWGWNocmlzLnNjaHVsdHpAaXJkLmdvdnQubnowHhcNMTEwOTE1MDIwNjIwWhcNMjEwOTEyMDIwNjIwWjCByTELMAkGA1UEBhMCTloxDTALBgNVBAgTBFdHVE4xEzARBgNVBAcTCldlbGxpbmd0b24xGDAWBgNVBAoTD0lSRFN0dWR5bGlua0IyQjEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxJTAjBgNVBAMTHHNpZ24tYW5kLWVuYy5kZXYuaXJkLmdvdnQubnoxFTATBgNVBCkTDHNpZ24tYW5kLWVuYzEoMCYGCSqGSIb3DQEJARYZY2hyaXMuc2NodWx0ekBpcmQuZ292dC5uejCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAykyZHVnXjsG220zB3kNOsGBeGP2rdNbLlIqW1D8yZO1fcj3/RhRiqsopbUrb8AU1ClpfhbH2K68kg7V91VAY0qrwNxP+pPPo1vYKMU6pT38qJGQzffr+iV2BCJshZvSk9E7QSWO5mFNstdg19xc+5ST1Lgb3fefuRG2KZVxPx0sCAwEAAaOCAZUwggGRMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDQGCWCGSAGG+EIBDQQnFiVFYXN5LVJTQSBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBSczRKXKPe3Sin7eFrVXfI7MXckzzCB+QYDVR0jBIHxMIHugBSLWxPSZd9otEj16vhLyovMCI9OMaGByqSBxzCBxDELMAkGA1UEBhMCTloxDTALBgNVBAgTBFdHVE4xEzARBgNVBAcTCldlbGxpbmd0b24xGDAWBgNVBAoTD0lSRFN0dWR5bGlua0IyQjEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxHjAcBgNVBAMTFWRldmNhLmIyYi5pcmQuZ292dC5uejEXMBUGA1UEKRMORGV2ZWxvcG1lbnQgQ0ExKDAmBgkqhkiG9w0BCQEWGWNocmlzLnNjaHVsdHpAaXJkLmdvdnQubnqCCQDL/qDdlx2j6DATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADgYEAS4ZPIVVpgTOGN4XcIC3SiYlxF8wYg7qnUhH5wJsAD3VCKfj68j9FSJtdBWLlWvvRxEoDP2lZ0IbFl6Rjnl+2ibzFnyac2G1AVm5mwPrNKHBQJ9J5eDJi0iUVY7Wphz86tKnqj34GvlHPNXmrF7oGEcDhPwK0T8zRdE/pvKIUiJc=</wsse:BinarySecurityToken>
<ds:Signature Id="Signature-2" 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/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#CertId-D05E596B5ABC341FEB13505090224061">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>3iVAUEAt8vAb7Ku+jf2gwSkSm0Q=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#UsernameToken-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>r4HLEAWJldJwmEmcAqV6Y8rnTPE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
YGh2I3VcukqjT0O7hKItiykWN5tlID18ZXRCwQjXriHmnVsO4wGcHjWfmhuNDecq+xRN+SjG8E7M
2Rx/5/BbFKbVlNOkQOSbSxIs1YT9GaThK16pMrX5KRkkJme1W3R0pGIIQh6gGRSUf79RZUIYxyVl
LqdIe561TXXDdtbt/6Q=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-D05E596B5ABC341FEB13505090224372">
<wsse:SecurityTokenReference wsu:Id="STRId-D05E596B5ABC341FEB13505090224373" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Reference URI="#CertId-D05E596B5ABC341FEB13505090224061" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>XXXXXX</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXX</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<ebxml:Messaging xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ebxml:UserMessage>
<ebxml:MessageInfo>
<ebxml:Timestamp>2002-02-02T14:18:02.0Z</ebxml:Timestamp>
<ebxml:MessageId>bf9433d9-c6e9-4c12-9c98-724008a09c21</ebxml:MessageId>
</ebxml:MessageInfo>
<ebxml:PartyInfo>
<ebxml:From>
<ebxml:PartyId type="identifier">Trading Partner X</ebxml:PartyId>
<ebxml:Role>Provider</ebxml:Role>
</ebxml:From>
<ebxml:To>
<ebxml:PartyId type="identifier">XXXXXXX</ebxml:PartyId>
<ebxml:Role>Requestor</ebxml:Role>
</ebxml:To>
</ebxml:PartyInfo>
<ebxml:CollaborationInfo>
<ebxml:AgreementRef>urn:XXXXXXXXX</ebxml:AgreementRef>
<ebxml:Service type="Web Service">urn:XXXXXXXX</ebxml:Service>
<ebxml:Action>customerInformation</ebxml:Action>
<ebxml:ConversationId>e302426a-b2d9-4ff1-a14b-fbbc2f40a017</ebxml:ConversationId>
</ebxml:CollaborationInfo>
</ebxml:UserMessage>
</ebxml:Messaging>
</soapenv:Header>
<soapenv:Body>
<urn:ConnectionTest>
<Message>Bonjour</Message>
</urn:ConnectionTest>
</soapenv:Body>
</soapenv:Envelope>
Нам предоставили некоторую документацию. Раздел безопасности скопирован ниже
Для каждого запроса в следующем порядке должна применяться следующая безопасность: Wsse: UsernameToken должен быть включен и содержать:
- Имя портала агента для значения элемента wsse: Username
-
Пароль портала агента для значения wsse: PasswordText (чистый текст) в элементе Password Блок подписи: Цифровые подписи создаются с использованием сертификатов x509. Каждому поставщику программного обеспечения требуется хранить и защищать действительный сертификат и закрытый ключ, выпущенные [To Be Determined]. При каждом запросе на обслуживание программное обеспечение должно:
-
Включить сертификат, который соответствует закрытому ключу, используемому для подписи как wsse: BinarySecurityToken, и использовать его как wsse: SecurityTokenReference для Подписи
- Подпишите wsse: BinarySecurityToken
- Подпишите wsse: UsernameToken
- Использовать алгоритм метода канонизации: http://www.w3.org/2001/10/xml-exc-c14n#
- Алгоритм метода подписи: http://www.w3.org/2000/09/xmldsig#rsa-sha1
- Использовать алгоритм метода дайджеста: http://www.w3.org/2000/09/xmldsig#sha1