Я создаю веб-службу WCF с настраиваемой конечной точкой привязки, и я застрял, принимая заголовок WS-Security, который отправляется мне другой стороной. Мы оба следуем спецификации, разработанной Национальной службой здравоохранения Великобритании, поэтому я не могу внести изменения в требования.Принимая как UsernameToken, так и BinarySecurityToken в WCF customBinding
Основная структура заголовка <wsse:Security>
должно быть следующим, в соответствии со спецификацией:
<wsse:Security>
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd" wsu:Id="6CCF6A2B-11A6-11DF-86D1-236A99759561" >
<wsu:Created>2012-06-12T09:00:00Z</wsu:Created>
<wsu:Expires>2012-06-12T09:15:00Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken>
<wsse:Username>SomeUsername</wsse:Username>
</wsse:UsernameToken>
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsssoap-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="30b91ede-35c2-11df-aac9-97f155153931 ">xxx...</wsse:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#RSA-SHA1" />
<Reference URI="#6CCF6A2B-11A6-11DF-86D1-236A99759561" />
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>xxx...</DigestValue>
</SignedInfo>
<SignatureValue>xxx...</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#30b91ede-35c2-11df-aac9-97f155153931 "/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
В моем веб-службы, я пытался использовать следующие привязки:
<customBinding>
<binding name="wsHttpSoap11" >
<textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
<security authenticationMode="MutualCertificate">
</security>
<httpTransport/>
</binding>
</customBinding>
(Причина, по которой я использую customBinding, заключается в том, что я должен поддерживать как WS-Addressing, так и WS-Security over SOAP 1. 1, и принял совет от this answer)
Если я запускаю запрос на образец через Скрипач, я получаю следующее сообщение об ошибке в моей WCF след:.
Cannot find a token authenticator for the 'System.IdentityModel.Tokens.UserNameSecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.
Я считаю, что это происходит потому, что он не может проверить подлинность <UsernameToken>
, Если изменить привязку к безопасности:
<security authenticationMode="UserNameForCertificate">
Тогда я получаю эту ошибку:
Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.
Я считаю, что это происходит потому, что теперь он не может проверить подлинность <BinarySecurityToken>
!
Вопрос, таким образом, является:
- ли мои предположения правильно о причине сообщения об ошибках (что он может обрабатывать только один маркер в его текущей конфигурации)?
- Как настроить его для приема обоих токенов?
Update
Благодаря @Yaron я теперь добавил пользовательские связывания расширения и оба UserNameSecurityToken и X509SecurityToken выполняется проверка.
Однако теперь он не работает на этапе, где он проверяет подпись XML. Исключение возвращается в ответе HTTP является:
Message security verification failed.
Если я копаю глубже в трассировку стека в окне просмотра службы трассировки, я вижу:
System.Security.Cryptography.CryptographicException...
The signature verification failed.
at System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter) at System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)...
Может кто-нибудь помочь мне понять, почему это происходит ? На данный момент я немного потерялся. Я попытался использовать some sample code, чтобы попытаться вручную проверить подпись, но он говорит, что подпись недопустима. Как я могу быть уверен, что это или нет, прежде чем я вернусь к поставщику? Это что-то, что должно работать? Должны ли мы делиться некоторыми сертификатами где-то вдоль линии?
Большое спасибо за ваш ответ - я попробую это, когда вернусь в офис завтра. Я упомянул в своем вопросе, что я использую SOAP 1.1, это влияет на ваш пример кода? –
Не влияет, однако, если мы обращаемся к адресату, это также может повлиять. Если у вас возникнут какие-либо проблемы, пожалуйста, опубликуйте полное мыло или отправьте его мне. –
. Пожалуйста, ознакомьтесь с моим обновлением. Рад отправить вам полный запрос, если он будет полезен. –