Showing posts with label wsHttpBinding. Show all posts
Showing posts with label wsHttpBinding. Show all posts

Saturday, June 18, 2016

WCF Security Notes


SYMMETRIC BINDING (WHEN ONLY SERVER HAS THE X509 CERT)









In case of derived key scenario –

2 keys are generated from symmetric key (derived keys). 1 key is used for encryption, while the other is used for signing. The client encrypt both derived keys.



      ASYMMETRIC BINDING ( BOTH CLIENT AND SERVER HAVE X509 CERT)




Although Derived keys can be used for Asymm binding as well, it will be of no use as Encryption and Signing are already happening with different keys.

If you want to use Asymmetric binding, you can ONLY do it via code. Only configuration will not suffice.
First create a custom binding inheriting from Binding class. Then add a BindingExtension and use that bindingextension in the endpoint binding configuration.


WCF by default uses SYMMETRIC KEY with DERIVED KEYS on. You cannot switch to make DERIVED KEYS off UNLESS you make a ‘custom binding’.


                                                     Best of both worlds – 





If negotiateServiceCredential=”true”, then the public key is given to the Client in the beginning of the transaction, however note that IT IS NOT INTEROPERABLE.
To make it interoperable, public key has to given to client by out-of-band mechanism.
Since client has the public key part of the certificate, it can verify the service (by the checking the trusted CA store). Client authenticates the server by using the <identity> element inside <client> element.

Note – Even if the ProtectionLevel of a operation is set to None, its body will be in clear text BUT its message header will have an encrypted section as client credentials are being passed.

Even if client has its own pvk key for authentication to service, WCF defaults to Symmetric binding with DERIVED keys. If you want to override this behavior (i.e use asymmetric binding), you have programmatically create a custom binding and use it client and service end.


Tuesday, January 6, 2015

Creating WCF service with multiple endpoint (one service, two endpoint)

Requirement - To have a single service, exposing two endpoints (basicHttpBinding, wsHttpBinding).

The web.config of the service needs to be updated with two endpoints. This web.config can be updated with "WCF configuration Editor" tool.

Here is the sample configuration -


<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding1">
          <readerQuotas maxDepth="99999" maxStringContentLength="99999"
            maxArrayLength="99999" maxBytesPerRead="99999" maxNameTableCharCount="99999" />
        </binding>
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="wsHttpBinding1">
          <readerQuotas maxDepth="99999" maxStringContentLength="99999"
            maxArrayLength="99999" maxBytesPerRead="99999" maxNameTableCharCount="99999" />
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="TestWCFServiceWSBinding.Service1">
        <endpoint address="/epWs" binding="wsHttpBinding"
          bindingConfiguration="wsHttpBinding1" name="EP_WsHttp" contract="TestWCFServiceWSBinding.IService1" />
        <endpoint address="/epBasic" binding="basicHttpBinding"
          bindingConfiguration="basicHttpBinding1" name="EP_BasicHttp"
          contract="TestWCFServiceWSBinding.IService1" />
        <host>
          <baseAddresses>
            <add baseAddress="http://MikePC:9650/Service1.svc"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>




The key here is have a base address present and different relative address for both the endpoints (marked in red). While consuming this service, the client must mention which endpoint its referring by -

 ServiceReference1.Service1Client cl = new ServiceReference1.Service1Client("EP_WsHttp");
            var x = cl.GetData(5);

 ServiceReference1.Service1Client cl2 = new ServiceReference1.Service1Client("EP_BasicHttp");
            var y = cl2.GetData(5);


Once it is implmented, verify in Fiddler - Traffic for basicHttpBinding call will be in plain text while for wsHttpBinding, it will be encrypted.