I have a windows service hosting a WCF service with the following configuration.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Carglass.Movil.Service.CarglassService" behaviorConfiguration="CarglassServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9002/CarglassServiceAGI" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="Carglass.Movil.Service.ICarglassService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CarglassServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<serviceCertificate findValue="CN=MWMWCF"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The certificate is installed on the machine and the Network Service user is running the windows service as local administrator. Permissions has been granted by running the following command
netsh http add urlacl url=http://+:9002/CarglassServiceAGI user="NT AUTHORITY\NETWORK SERVICE"
... and by managing private keys within mmc.exe giving "Full control" to that user.
But I got the following exception every time I try to run my service:
System.ArgumentException: It is likely that certificate 'CN=MWMWCF' may not have a private key that is capable of key exchange or the process may not have access rights for the private key. Please see inner exception for detail.\r\n at System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate)\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateServerX509TokenProvider()\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirement)\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateTlsnegoServerX509TokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateTlsnegoSecurityTokenAuthenticator(RecipientServiceModelSecurityTokenRequirement recipientRequirement, Boolean requireClientCertificate, SecurityTokenResolver& sctResolver)\r\n at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, SecurityTokenResolver& outOfBandTokenResolver)\r\n at System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.SessionRenewSecurityTokenManager.CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, SecurityTokenResolver& outOfBandTokenResolver)\r\n at System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.SecurityProtocolFactory.Open(Boolean actAsInitiator, TimeSpan timeout)\r\n at System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout)\r\n at System.ServiceModel.Channels.SecurityChannelListener
1.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.SecurityUtils.OpenCommunicationObject(ICommunicationObject obj, TimeSpan timeout)\r\n at System.ServiceModel.Security.SecurityUtils.OpenTokenAuthenticatorIfRequired(SecurityTokenAuthenticator tokenAuthenticator, TimeSpan timeout)\r\n at System.ServiceModel.Security.SecuritySessionServerSettings.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.SecuritySessionServerSettings.Open(TimeSpan timeout)\r\n at System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout)\r\n at System.ServiceModel.Channels.SecurityChannelListener
1.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)\r\n at System.ServiceModel.Channels.CommunicationObject.Open()\r\n at MWM.Service.WindowsService.AGI.ServiceController.OnStart(String[] args) in c:\TeamCity\buildAgent\work\MWM-Refactor\MWM.Service\MWM.Service.WindowsService.AGI\ServiceController.cs:line 45
Works fine if I remove this from the configuration:
<message clientCredentialType="Certificate"/>