WCF wsHttpBinding with certificate message security - wcf

I am trying to create client and service applications with Message security with Certificate. But I have some errors all the time and can't make it work. Could somebody suggest what is wrong with my configuration files?
This is the service configuration:
<system.serviceModel>
<services>
<service name="SecuredCommunication.Service1" behaviorConfiguration="securedBehavior">
<endpoint address="test" binding="wsHttpBinding" bindingName="test" name="fasds" bindingConfiguration="securedWsBinding" contract="SecuredCommunication.IService1" >
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="securedWsBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="securedBehavior">
<serviceMetadata httpGetBinding="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<serviceCertificate findValue="wcftest.pvt" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
and this is the test client configuration
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<clientCertificate findValue="wcftest.pvt" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding>
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://wcftest.pvt/SecuredCommunication/Service1.svc" binding="wsHttpBinding" contract="SecuredCommunication.IService1">
</endpoint>
</client>
the current exception I have is:
System.ServiceModel.ServiceActivationException: The requested service, 'http://wcftest.pvt/SecuredCommunication/Service1.svc' could not be activated. See the server's diagnostic trace logs for more information.
For me configuration looks ok, I created it using some manuals from MSDN, so I can't understand what is wrong.
I installed certificate using makecert.exe tool like this
makecert.exe MakeCert -pe -ss My -sr LocalMachine -a sha1 -sky exchange -n CN=wcftest.pvt
Thanks,
Alexander.

In the service configuration, replace
<serviceMetadata httpGetBinding="true"/>
by
<serviceMetadata httpsGetBinding="true"/>
This matches the secure channel configuration applied in the bindings.

Related

WCF service connection error: "The request for security token has invalid or malformed elements"

I set up certificate-based authentication for a WCF service. It works when the service and the client are running on the same computer, but now I have deployed them to different computers, I encounter "The request for security token has invalid or malformed elements".
It seems like this is usually a certificate error. I don't see what is wrong with the setup.
The server has the following certificates installed:
MyRoot in Local Machine\Trusted CAs
MyServer in Local Machine\Personal (with the private key)
The client has the following certificates installed:
MyRoot in Local Machine\Trusted CAs
MyClientCert in Local Machine\Personal (with the private key)
The client configuration is like this:
<system.serviceModel>
<client>
<endpoint address="http://10.0.0.4:8000/Handshake" binding="wsHttpBinding" behaviorConfiguration="ClientCertificateBehavior"
bindingConfiguration="WSHttpBinding_IHandshaker" contract="IHandshaker"
name="WSHttpBinding_IHandshaker"/>
</client>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHandshaker">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="MyClientCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
The service configuration is like this:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="gzipBinding">
<gzipMessageEncoding />
<sslStreamSecurity />
<tcpTransport>
</tcpTransport>
</binding>
</customBinding>
<wsHttpBinding>
<binding name="ClientCertAuthenticationBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Rdt.CertificateIdentification.ClientAuthentication.HandshakeService" behaviorConfiguration="HandshakeServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://10.0.0.4:8000/Handshake"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ClientCertAuthenticationBinding" contract="OCS.Client.KnownLayer.IHandshaker"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HandshakeServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceCredentials>
<serviceCertificate findValue="MyServer" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
1.You need to specify the DNS value in the client configuration, WcfServer is the name of your server certificate,here is a tutorial on how to use the certificate correctly.
<client>
<endpoint address="" binding="" bindingConfiguration="" contract="" name="" behaviorConfiguration="">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
2.There is one more </client> in your service configuration.
3.You can try to set <security mode="Message"> in the client configuration.

request for a specific client certificate in nettcp bindings

Is it possible to configure net tcp binding
to request a specific certificate to be supplied by the client ?
not just certificate which is trusted by the server but the exact same certificate defined in the server ?
Thanks
You use netTcpBinding and need a specific certificate to verify, you can view my demo.
This is the app.config in service:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.X509CertificateValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address provided by host -->
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8040/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate" binding="netTcpBinding" bindingConfiguration="Binding" contract="Microsoft.Samples.X509CertificateValidator.ICalculator"/>
</service>
</services>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
In the behavior node, we can specify the information of the certificate to be used.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Microsoft.Samples.X509CertificateValidator.CustomX509CertificateValidator, service"/>
</clientCertificate>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
This is the app.config in client:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<client>
<!-- X509 certificate based endpoint -->
<endpoint name="Certificate" address="net.tcp://localhost:8040/servicemodelsamples/service/certificate" binding="netTcpBinding" bindingConfiguration="Binding" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.Samples.X509CertificateValidator.ICalculator">
</endpoint>
</client>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
In client.cs, we need to specify the certificate to be used through the setcertificate method.
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "alice");

Implement transport security on my WCF service with custombinding on HTTP

I am new to WCF security . I am trying to implement transport security on my WCF service. We are using custombinding on HTTP. Can someone please suggest how can we do that?
<customBinding>
<binding name="CustomBinding">
<binaryMessageEncoding/>
<httpTransport allowCookies="true" maxReceivedMessageSize="2000000000" maxBufferSize="2000000000" maxBufferPoolSize="2000000000"/>
</binding>
</customBinding>
You're going to want to use Certificates to achieve transport-level security.
You can use this tutorial (below) on how to create "test" certs; for production I'd advise either issuing a cert using your own company's internal CA (if they have one) or use a trusted provider (Symantec, GlobalSign, etc).
http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.110).aspx
You can use this tutorial (below) on how to install the certificate(s) on the box(es).
http://msdn.microsoft.com/en-us/library/bb950259(v=bts.10).aspx
As far as the service app.config -- it should be something like the below:
<system.serviceModel>
<services>
<service name="YourServiceNameGoesHere" behaviorConfiguration="MyCustomBehavior">
<endpoint address="YourAddressGoesHere" binding="customBinding" contract="YourIContractNameGoesHere" bindingConfiguration="MyCustomBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyCustomBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" trustedStoreLocation="LocalMachine" />
</clientCertificate>
<serviceCertificate findValue="YourCertNameGoesHere" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="MyCustomBinding">
<security authenticationMode="CertificateOverTransport" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
As far as the client app.config -- it should be something like the below:
<system.serviceModel>
<client>
<endpoint address="YourAddressGoesHere" binding="customBinding" bindingConfiguration="MyCustomBinding" behaviorConfiguration="MyCustomBehavior" contract="YourIContractNameGoesHere" name="YourClientNameGoesHere" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="MyCustomBehavior">
<clientCredentials>
<clientCertificate findValue="YourCertNameGoesHere" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="MyCustomBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
<httpsTransport />
</binding>
</customBinding>
</bindings>
</system.serviceModel>

Client certificate authentication WCF

So I'm completely lost with certificates. I've searched all over the web for solutions and tutorials for this and found nothing that can really help me.
What I'm trying to do is to have both server and client certificate validation for my WCF client-server application. The application is hosted on IIS.
I want it on my dev computer (the server is localhost) and in test (where im the client and the server is a windows server).
the configuration I have now is:
Client:
<behaviors>
<endpointBehaviors>
<behavior name="myBehaviorConfig">
<clientCredentials>
<clientCertificate findValue="CN=MyTestClientCertificate"
storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="MyBindingConfig">
<security mode="TransportWithMessageCredential">
<transport realm=""/>
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/Service.Calculator.svc"
binding="wsHttpBinding"
bindingConfiguration="MyBindingConfig"
behaviorConfiguration="MyBehaviorConfig"
contract="Service.ICalculator"
name="ICalculatorServiceEndpoint">
<identity>
<servicePrincipalName value="host"/>
</identity>
</endpoint>
</client>
Server:
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceCredentials>
<serviceCertificate findValue="CN=MyTestRootCA"
storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName"/>
<userNameAuthentication userNamePasswordValidationMode="Windows"/>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</clientCertificate>
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<unity operationContextEnabled="true"
instanceContextEnabled="true"
contextChannelEnabled="true"
serviceHostBaseEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="MyBinding">
<security mode="TransportWithMessageCredential">
<transport realm=""/>
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service.Calculator"
behaviorConfiguration="myBehavior">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="MyBinding"
contract="Service.ICalculator" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"
name="CalculatorServiceMex" />
</service>
</services>
"CN=MyTestRootCA" is the "Authority" the "Creating" certificate and I put him in the trusted root certificates on the localComputer as well as in the personal directory in the local computer.
And it is the issuer of the client certificate "CN=MyTestClientCertificate".
Few things..
I know that the client certificate should be in the CurretUser directory in the "MMC" but when its there i have an exception that the app can't find the certificate.
I tried locating it by "FindBySubjectDistinguishedName" and with "FindByThumbprint", both time was the same exception "Cant find certificate with the given criteria ..." so i put it in the LocalMachine and its fine.
Any one has an idea why it didn't work?
I had lots of problems and exceptions with this =\ the current one is:
"The private key is not presented in the X.509 certificate"
Anybody familiar with this exception and know how to fix it?
thanks a lot for your answers, i'm sitting on this for few days now
Your configuration file does not specify the clientCertificate storeLocation value, therefore the client certificate needs to be in the LocalMachine store, which is the default value for storeLocation.
Consider the following example from msdn which sets the client certificate store location:
<clientCertificate>
<certificate
findValue="www.cohowinery.com"
storeLocation="CurrentUser"
storeName="TrustedPeople"
x509FindType="FindByIssuerName" />
<authentication …
Note: the other error, “The private key is not presented in the X.509 certificate”, is mostly likely thrown because your certificate does not have an associated private key or your process’ user context does not have permission to access the private key.

WCF Service: behavior with serviceCredentials with certificate - how should I configure it for Azure?

I have simple WCF Service Service1 with the following config:
<behaviors>
<serviceBehaviors>
<behavior name="SecuredBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
<serviceCredentials type="System.ServiceModel.Description.ServiceCredentials">
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFS.Service1,WCFS"/>
<serviceCertificate findValue="BasicWCFCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<windowsAuthentication includeWindowsGroups="false"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="SecuredWsHttpBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WCFS.Service1" behaviorConfiguration="SecuredBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SecuredWsHttpBinding"
name="End1" contract="WCFS.IService1" />
</service>
</services>
So on my development machine I'm using this service with certificate "BasicWCFCert" stored in LocalMachine in "My" (Personal) location.
How should I change it before publishing this service in Azure?
How can I tell Service1 to use one of certificates uploaded to Azure?
Have you tried attaching the cert in the role configuration screen as show below?
You can get the thumbprint by running certmgr.msc and going to the relevant certificate.