I would like to implement WCF service with server and client certificates.
When I try to connect to service on IIS I get the following error:
Test method
TestProject1.UnitTest1.TestMethod1
threw exception:
System.ServiceModel.Security.SecurityNegotiationException:
Secure channel cannot be opened
because security negotiation with the
remote endpoint has failed. This may
be due to absent or incorrectly
specified EndpointIdentity in the
EndpointAddress used to create the
channel. Please verify the
EndpointIdentity specified or implied
by the EndpointAddress correctly
identifies the remote endpoint. —>
System.ServiceModel.FaultException:
The request for security token has
invalid or malformed elements..
My web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="DotNetStoreBinding" receiveTimeout="00:00:15">
<reliableSession inactivityTimeout="00:00:20" />
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="WcfServiceCustumer.Service1">
<endpoint binding="wsHttpBinding" contract="WcfServiceCustumer.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true"/>
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" findValue="CN=DotNetStore" />
<clientCertificate>
<certificate storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectDistinguishedName" findValue="CN=Bob"/>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
</serviceCredentials>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
After I have created server I created new project and added service reference. I call the service like this:
EndpointAddress address = new EndpointAddress(
new Uri("http://localhost/CustomerServiceSite/Customer.svc"),
EndpointIdentity.CreateDnsIdentity("DotNetStore"),
new AddressHeaderCollection()
);
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
var client = new CustomerService.Service1Client(binding, address);
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=Bob");
IList<Product> allProducts = client.GetAllProducts();
Any help would be appreciated.
The problem was occuring becouse of certificates. I did not have correct pairs on client and service.
A good description how to correctly use certificates can be found here:
http://www.codeproject.com/KB/WCF/9StepsWCF.aspx?msg=3181718