request for a specific client certificate in nettcp bindings - wcf

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");

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.

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>

Securing WCF with basichttpbinding

I am using basicHttpBinding,message security and x509 certificate in my WCF service(.Net Framework 4.0).The config looks like this:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="MyWebSite" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="CToSave.ValidateClient, CToSave" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="True"/>
</webScriptEndpoint>
</standardEndpoints>
<services>
<service behaviorConfiguration="ServiceBehavior" name="CToSave.MyService">
<endpoint address="" binding="basicHttpBinding" contract="CToSave.IMyService" bindingConfiguration="BindingConfig"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BindingConfig" openTimeout="00:50:00" sendTimeout="00:50:00" receiveTimeout="00:50:00" closeTimeout="00:50:00" maxReceivedMessageSize="2147483647">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
A PHP client will be consuming this service. In order to consume it,will the client need a certificate at his end?I would prefer that the client doesnt have to generate a certificate.
If the clinet has to get a certificate,will my config change? If yes,what changes will I have to make?
I have read dozens of articles on basihttpbinding+security but none of them indicate anything about the certificate on the client-side. Please help.
Yes, client needs a certificate because of this:
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
In general client does not generate its own certificate but gets it from agree provider (can be cert authority in the organization or a public authority or service owner).
In any case you need a good WS-Security library for PHP since you need to generate the message format WCF expects (this is message level security).
Actually it is possible to validate certificate by identity on a client

WCF error The client certificate is not provided. Specify a client certificate in ClientCredentials

I am trying to call a WCF service .I created a selfsigned certificate and installed in my localmachine \personnal \certificates , and also I added that in my section .But I don't understand why this error is .
Here is my web.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://abcdxyz.abc.syntax.com/TestCCService.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
contract="TestCCService.ITestCCService" name="wsHttpEndpoint" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="abc.mymachine.name.com" x509FindType="FindBySubjectName"
storeLocation="LocalMachine" storeName="My" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
but when I try to call my service method its throwing errors
"The client certificate is not provided. Specify a client certificate in ClientCredentials."
Appreciate your suggestions to resolve this error ?
I forgot to include behaviorConfiguration="CustomBehavior"
<endpoint address="https://abcdxyz.abc.syntax.com/TestCCService.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
contract="TestCCService.ITestCCService" name="wsHttpEndpoint" **behaviorConfiguration="CustomBehavior"** />
and its working now .
Thank you for help

Pass ClientCredentials.UserName to server

Web config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceCredentialsBehavior">
<serviceCredentials>
<serviceCertificate findValue="cool" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceCredentialsBehavior" name="Service">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MessageAndUserName" name="SecuredByTransportEndpoint" contract="IService"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MessageAndUserName">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client/>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
Client cfg:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" >
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:48097/WCFServer/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<dns value ="cool" />
</identity>
</endpoint>
</client>
</system.serviceModel>
The scope is to pass ClientCredentials.UserName.UserName/Password through a secure connection.
I did x509 certificates with pluralsight self cert..
The error is:
SOAP security negotiation with 'http://localhost:48097/WCFServer/Service.svc'
for target
'http://localhost:48097/WCFServer/Service.svc'
failed. See inner exception for more
details.
InnerException:
The X.509 certificate CN=cool chain
building failed. The certificate that
was used has a trust chain that cannot
be verified. Replace the certificate
or change the
certificateValidationMode. A
certificate chain processed, but
terminated in a root certificate which
is not trusted by the trust provider.
How can i solve this exception?
Regards,
Sergiu.
You are using self signed certificate which is not trusted by default. You must tell your client application that it should trust the certificate:
<behaviors>
<endpointBehaviors>
<behavior name="LocalCertValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Reference this behavior from your endpoint configuration in client by behaviorConfiguration="LocalCertValidation". To make it work you must install public certificate to current user's certification store under trusted people. You can also set validation mode to None and certificate will not be validated at all but that should be used only in development environment.