具有证书以及客户端和服务签名的 WCF 消息安全性
我们正在尝试使用 x509 证书实现客户端和 WCF 服务之间的消息安全。客户端发送 SOAP 安全标头,服务按预期验证标头。问题在于该服务没有使用我们需要的安全标头对其响应消息进行签名。我相信下面包含了所需的所有信息,但如果您需要其他信息,请告诉我。谢谢!
服务的 web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<services>
<service name="RealIdCardService.AetnaNavigator" behaviorConfiguration="serviceCredentialBehavior">
<endpoint address="" contract="RealIdCardService.IAetnaNav" binding="wsHttpBinding" bindingConfiguration="InteropCertificateBinding"></endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceCredentialBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" />
<serviceCredentials>
<!--certificate storage path in the server-->
<serviceCertificate findValue="WcfClient" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople" />
<issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
<!--certificate storage path in the client-->
<clientCertificate>
<certificate findValue="WcfServer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople" />
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="InteropCertificateBinding">
<security mode="TransportWithMessageCredential">
<!--security mode of certificate
establishSecurityContext="true"-->
<message negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="false" clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
<system.web>
<compilation debug="true" />
</system.web>
<system.webServer>
<handlers>
<remove name="StaticFile" />
</handlers>
</system.webServer>
</configuration>
客户端的 app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<!--
The clientCredentials behavior allows one to define a certificate to present to a service.
A certificate is used by a client to authenticate itself to the service and provide message integrity.
This configuration references the "client.com" certificate installed during the setup instructions.
-->
<clientCredentials>
<clientCertificate findValue="WcfServer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople"/>
<serviceCertificate>
<defaultCertificate findValue="qanav2.sourceonedirect.com"
storeLocation="LocalMachine"
storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<authentication revocationMode="NoCheck" certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_RealIdCardService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="655360"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1638400"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://qanav2.sourceonedirect.com/AetnaNavigator/RealIdCardService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_RealIdCardService"
contract="RealIdCardService" name="WSHttpBinding_RealIdCardService" />
</client>
</system.serviceModel>
</configuration>
来自客户端的显示消息安全性的请求:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://service.sourceOne.realIdcard.com/RealIdCardService/getImage</a:Action>
<a:MessageID>urn:uuid:5d1170db-cc7f-485b-9d19-e88edb49a957</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1" u:Id="_1">https://qanav2.sourceonedirect.com/AetnaNavigator/RealIdCardService.svc</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2011-08-11T16:39:51.548Z</u:Created>
<u:Expires>2011-08-11T16:44:51.548Z</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="uuid-8c46f875-8e7c-449d-ba8b-c9263a04db89-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">MIIBsTCCAV+gAwIBAgIQW2xiwVBnILpOlvTOe4BlezAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDgxMTE0NTA1M1oXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJV2NmU2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4xaSGyke2NPJfXOHtZBz3yHXIjl0nA4WxKWY5Ettgs0DxUU7UKONgEKTloYnkmmiiHjRHzbClfaAbPrDQEe/DihmohWKDGa6aQ1Cat+CsZDGDgLhIcv85n1uLNriA5CJ2ebwgOoh6VxOLOQvjfNGBGfQBSZDe7DMOPntjO7ryhQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBACfb7CnUN1dfyAgWbrxgwMr7wZgUo467YgT2+nOwiWlbbYJcqTx/5FkeVg3XXsaI2VINhUURrzvtJxFosKDzNR4=</o: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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>3Lo6p2VdFuYvSkrkqqxY06OseoM=</DigestValue>
</Reference>
<Reference URI="#_1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>n/l/ydDWJXU8w/T5oZhXNoH2ZI0=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>cLvhF1zEuaizz+SyaqKRWDmE/HF64ODiP0E6B1jEkRWwNdyp7qwgtZaTQj8qcJKYGi76HpZm6DOd+Re0561h/o8o/vD+ijVHvMZc0AF12MN/HgItNBmYF6ify0y6g9PLlc0SFCGc/1aeLDj5yZylYTmMdqgps77q0kCV8s6hmWo=</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-8c46f875-8e7c-449d-ba8b-c9263a04db89-1"/>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body>
<getImage xmlns="http://service.sourceOne.realIdcard.com/">
<arg0 xmlns:i="http://www.w3.org/2001/XMLSchema-instance"></arg0>
</getImage>
</s:Body>
</s:Envelope>
来自没有基于证书的安全性的服务的响应:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://service.sourceOne.realIdcard.com/RealIdCardService/getImageResponse</a:Action>
<a:RelatesTo>urn:uuid:5d1170db-cc7f-485b-9d19-e88edb49a957</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2011-08-11T16:39:57.496Z</u:Created>
<u:Expires>2011-08-11T16:44:57.496Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<getImageResponse xmlns="http://service.sourceOne.realIdcard.com/">
<getImageResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CumbID>W261748481</CumbID>
<HMOID i:nil="true"/>
<IDCardImage>/9j/QAxb/wATayS9uZhG </IDCardImage>
<MailDate>7/1/2011 12:00:00 AM</MailDate>
</getImageResult>
</getImageResponse>
</s:Body>
</s:Envelope>
We are attempting to implement message security between a client and WCF service using x509 certificates. The client sends the soap security headers and the service verifies the headers as expected. The problem is that the service is not signing it’s response message with security headers which we need. I believe below includes all of the information that is needed but let me know if you need anything else. Thanks!
The service’s web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<services>
<service name="RealIdCardService.AetnaNavigator" behaviorConfiguration="serviceCredentialBehavior">
<endpoint address="" contract="RealIdCardService.IAetnaNav" binding="wsHttpBinding" bindingConfiguration="InteropCertificateBinding"></endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceCredentialBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" />
<serviceCredentials>
<!--certificate storage path in the server-->
<serviceCertificate findValue="WcfClient" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople" />
<issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
<!--certificate storage path in the client-->
<clientCertificate>
<certificate findValue="WcfServer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople" />
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="InteropCertificateBinding">
<security mode="TransportWithMessageCredential">
<!--security mode of certificate
establishSecurityContext="true"-->
<message negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="false" clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
<system.web>
<compilation debug="true" />
</system.web>
<system.webServer>
<handlers>
<remove name="StaticFile" />
</handlers>
</system.webServer>
</configuration>
The client’s app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<!--
The clientCredentials behavior allows one to define a certificate to present to a service.
A certificate is used by a client to authenticate itself to the service and provide message integrity.
This configuration references the "client.com" certificate installed during the setup instructions.
-->
<clientCredentials>
<clientCertificate findValue="WcfServer" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople"/>
<serviceCertificate>
<defaultCertificate findValue="qanav2.sourceonedirect.com"
storeLocation="LocalMachine"
storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<authentication revocationMode="NoCheck" certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_RealIdCardService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="655360"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1638400"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://qanav2.sourceonedirect.com/AetnaNavigator/RealIdCardService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_RealIdCardService"
contract="RealIdCardService" name="WSHttpBinding_RealIdCardService" />
</client>
</system.serviceModel>
</configuration>
The request from the client showing the message security:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://service.sourceOne.realIdcard.com/RealIdCardService/getImage</a:Action>
<a:MessageID>urn:uuid:5d1170db-cc7f-485b-9d19-e88edb49a957</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1" u:Id="_1">https://qanav2.sourceonedirect.com/AetnaNavigator/RealIdCardService.svc</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2011-08-11T16:39:51.548Z</u:Created>
<u:Expires>2011-08-11T16:44:51.548Z</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="uuid-8c46f875-8e7c-449d-ba8b-c9263a04db89-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">MIIBsTCCAV+gAwIBAgIQW2xiwVBnILpOlvTOe4BlezAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDgxMTE0NTA1M1oXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJV2NmU2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4xaSGyke2NPJfXOHtZBz3yHXIjl0nA4WxKWY5Ettgs0DxUU7UKONgEKTloYnkmmiiHjRHzbClfaAbPrDQEe/DihmohWKDGa6aQ1Cat+CsZDGDgLhIcv85n1uLNriA5CJ2ebwgOoh6VxOLOQvjfNGBGfQBSZDe7DMOPntjO7ryhQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBACfb7CnUN1dfyAgWbrxgwMr7wZgUo467YgT2+nOwiWlbbYJcqTx/5FkeVg3XXsaI2VINhUURrzvtJxFosKDzNR4=</o: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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>3Lo6p2VdFuYvSkrkqqxY06OseoM=</DigestValue>
</Reference>
<Reference URI="#_1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>n/l/ydDWJXU8w/T5oZhXNoH2ZI0=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>cLvhF1zEuaizz+SyaqKRWDmE/HF64ODiP0E6B1jEkRWwNdyp7qwgtZaTQj8qcJKYGi76HpZm6DOd+Re0561h/o8o/vD+ijVHvMZc0AF12MN/HgItNBmYF6ify0y6g9PLlc0SFCGc/1aeLDj5yZylYTmMdqgps77q0kCV8s6hmWo=</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-8c46f875-8e7c-449d-ba8b-c9263a04db89-1"/>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body>
<getImage xmlns="http://service.sourceOne.realIdcard.com/">
<arg0 xmlns:i="http://www.w3.org/2001/XMLSchema-instance"></arg0>
</getImage>
</s:Body>
</s:Envelope>
The response from the service without the certificate based security:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://service.sourceOne.realIdcard.com/RealIdCardService/getImageResponse</a:Action>
<a:RelatesTo>urn:uuid:5d1170db-cc7f-485b-9d19-e88edb49a957</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2011-08-11T16:39:57.496Z</u:Created>
<u:Expires>2011-08-11T16:44:57.496Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<getImageResponse xmlns="http://service.sourceOne.realIdcard.com/">
<getImageResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CumbID>W261748481</CumbID>
<HMOID i:nil="true"/>
<IDCardImage>/9j/QAxb/wATayS9uZhG </IDCardImage>
<MailDate>7/1/2011 12:00:00 AM</MailDate>
</getImageResult>
</getImageResponse>
</s:Body>
</s:Envelope>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据您的描述,您的安全设置完全错误。您想要在消息中签名吗? =>您需要消息安全性,但您正在使用传输安全性并且仅传递证书作为客户端标识。这有几个含义:
如果您想在请求和响应中都有签名必须转向完全消息安全(不需要 HTTPS),这意味着将安全模式从
TransportWithMessageSecurity
更改为Message
。之后,客户端和服务都将拥有自己的证书,并使用它们分别保护每条消息。默认情况下,您的消息的全部内容也将被加密和签名。如果您不想要它,则必须在合约上配置ProtectionLevel
。Your security setting is completely wrong based on your description. You want signatures in message? => you need message security but you are using transport security and only passing certificate as client identification. That has several implications:
If you want to have signatures in both request and response you must move to full message security (HTTPS will not be needed) which means changing security mode from
TransportWithMessageSecurity
toMessage
. After that both client and service will have its own certificate and use them to secure each message separately. By default whole content of your message will be also encrypted and signed. If you don't want it you must configureProtectionLevel
on your contracts.