Implement transport security on my WCF service with custombinding on HTTP - wcf

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>

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

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.

WCF wsHttpBinding with certificate message security

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.

WCF problem with POSTs using ssl (https)

I currently have a webHttp binding WCF restful service, it works great over http, I can make Post of large sizes due to my webconfig settings, now I am trying to use it over https (ssl), now my gets work fine, but my posts dont, it doesnt work when the file size is over a certain amount, i was wondering why this could be since my webconfig specifies a larger size and it works good over http, here is my relevant webconfig.. any suggestions
Thanks
<system.serviceModel>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="webHttp"
contract="PrimeStreamInfoServices.IService1" name="Client" />
</client>
<bindings>
<webHttpBinding>
<binding name="webHttp" maxBufferSize="15000000" maxBufferPoolSize="15000000"
maxReceivedMessageSize="15000000">
<readerQuotas maxDepth="15000000" maxStringContentLength="10000000"
maxArrayLength="15000000" maxBytesPerRead="15000000" maxNameTableCharCount="10000000" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="string" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="PrimeStreamInfoServices.Service1Behavior"
name="PrimeStreamInfoServices.Service1">
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="webHttp" contract="PrimeStreamInfoServices.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PrimeStreamInfoServices.Service1Behavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<!--
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="TempCa" />
-->
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
If you want to use webHttpBinding over SSL then you have configure your binding to use transport security like:
<security mode="Transport">
This link provides some details with sample config to deal with the following error:
Could not find a base address that matches scheme http for the
endpoint with binding WebHttpBinding. Registered base address schemes
are [https]
Sample config from the blog:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="TestServiceAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="TestService">
<endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="webBinding" contract="TestService" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>