Reputation: 841
I am developing a WCF web service and WCF client application which should sign their SOAP messages bodies with certificates.
I have enabled [ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]
in my Service interface.
Service Web.config configuration
<system.serviceModel>
<services>
<service name="ApsService.Service" behaviorConfiguration="ApsServiceBehaviour">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="ApsService.IService">
<identity>
<dns value="WcfClient"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding"/>
</protocolMapping>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding" >
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ApsServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
<certificate x509FindType="FindBySubjectName"
findValue="WcfClient" storeName="TrustedPeople" storeLocation="LocalMachine" />
</clientCertificate>
<serviceCertificate x509FindType="FindBySubjectName"
findValue="WCfServer" storeName="TrustedPeople" storeLocation="LocalMachine" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<authentication revocationMode="NoCheck" customCertificateValidatorType="ApsService.ApsCertificatesValidator,ApsService"
certificateValidationMode="Custom" />-->
</system.serviceModel>
Client App.config configuration
<system.serviceModel>
<client>
<endpoint address="http://localhost/ApsService/Service.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
contract="ApsService.IService" name="WSHttpBinding_IService">
<identity>
<dns value="WCfServer" />
</identity>
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<clientCertificate findValue="WcfClient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
<defaultCertificate findValue="WCfServer" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
The problem is what I am getting MessageSecurityException exception with the text "The primary signature must be encrypted." when the web-service trying to send a response to the client application. I can't find how to fix that problem, may be something missing from my configuration?
Upvotes: 1
Views: 2934
Reputation: 405
Not sure if this would maybe help anyone, but I recently had this issue. In my case the solution was upgrading the project to a more recent .NET version.
Upvotes: 0
Reputation: 4615
The same error occurs if you forgot to set the protection level.
[ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]
Upvotes: 0
Reputation: 841
The problem is solved by custom binding, it disables signature confirmation by:
requireSignatureConfirmation="false"
Client app.config
<client>
<endpoint address="http://localhost/ApsService/Service.svc" binding="customBinding" bindingConfiguration="WSHttpBinding_IService"
contract="ApsService.IService" name="WSHttpBinding_IService">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
<bindings>
<customBinding>
<binding name="WSHttpBinding_IService">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSignatureConfirmation="false" canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default"
authenticationMode="MutualSslNegotiated" requireDerivedKeys="true"
includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSignatureConfirmation="false">
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</secureConversationBootstrap>
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<clientCertificate findValue="WcfClient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
<defaultCertificate findValue="WCfServer" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Upvotes: 2