Secure a TCP – WCF service at the Message level

When building and using WCF services to exchange messages over the wire, you must always take into account security. In one line, security is concerned with protecting users running client applications, services and the messages passing between them. These messages may contain private user information such as passwords, bank accounts credentials etc. Also, usually the service must ensure that the client is the one who claims to be and respectively, the client must know  that it’s messages are sent to the right destination service. This post will show you how to implement TCP message level security by encrypting messages exchanged between client and service.  In a previous post we saw how to host and consume a WCF service over TCP. We will configure NetTcpBinding binding in the Web.config file of the service to encrypt messages at the message level. NetTcpBinding automatically encrypts data at the transport level by using Transport Layer Security (TLS) over TCP. Adding security at the message level, gives you a greater degree of security. Configure netTcpBinding of your WCF service to encrypt messages at the message level as follows.

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="AdventureWorks2012Entities" connectionString="metadata=res://*/AdventureWorksModel.csdl|res://*/AdventureWorksModel.ssdl|res://*/AdventureWorksModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=developer-PC;initial catalog=AdventureWorks2012;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="false" targetFramework="4.5">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="AdventureWorksServiceTcpBindingConfig">
          <security mode="Message">
            <message algorithmSuite="Basic128" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <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="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="AdventureWorks.AdventureWorksServiceImpl">
        <endpoint address="net.tcp://developer-pc/AdventureWorksService/Service.svc" binding="netTcpBinding"
                  bindingConfiguration="AdventureWorksServiceTcpBindingConfig" name="NetTcpBinding_AdventureWorksService"
                  contract="AdventureWorks.AdventureWorksService">
        </endpoint>
      </service>
    </services>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="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>

You can do that, straight forward in the Web.config file in you IIS folder. The netTcpBinding will now encrypt all messages using the Advance Encryption Standard (AES) 128-bit algorithm. This is a good and efficient encryption algorithm to use inside an organization. If you are sending messages over the Internet you may prefer to use the default algorithm, that is Basic256. Try to run the client application without making any changes yet. You should get an error like below.
securityex

This is normal though, since we told the service to encrypt messages before sending them to client, but we didn’t update client configuration to accept this kind of messages. At the moment, client expects normal and non-encrypted ones. So by the time he receives an encrypted message, an error will occur at some point in the channel’s stack processing. To resolve this, simply make the respective configurations in the App.config file of the client project as follows.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_AdventureWorksService" />
            </basicHttpBinding>
            <netTcpBinding>
              <binding name="NetTcpBinding_AdventureWorksService">
                <security mode="Message">
                  <message algorithmSuite="Basic128" />
                </security>
              </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/AdventureWorksService/Service.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_AdventureWorksService"
                contract="AdventureWorksServiceRef.AdventureWorksService"
                name="BasicHttpBinding_AdventureWorksService" />
            <endpoint address="net.tcp://developer-pc/AdventureWorksService/Service.svc"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_AdventureWorksService"
                contract="AdventureWorksServiceRef.AdventureWorksService"
                name="NetTcpBinding_AdventureWorksService">
                <identity>
                    <userPrincipalName value="developer-PC\developer" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

That’s it. Now there is an agreement between client and service on how they exchange messages. Build and run the client project again. You should receive no errors this time.

Advertisements


Categories: WCF

Tags:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Chara Plessa

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Kumikoro

A Front End Developer's Blog

Muhammad Hassan

Full Stack Developer | ASP.NET | MVC | WebAPI | Advanced Javascript | AngularJS | Angular2 | C# | ES6 | SQL | TypeScript | HTML5 | NodeJS, MS candidate @LUMS, Grad & EX-Adjunct Faculty @NUCES-FAST, seasonal blogger & open-source contributor. Seattle, WA.

Software Engineering

Web development

IEvangelist

.NET, ASP.NET, C#, MVC, TypeScript, AngularJS

leastprivilege.com

Dominick Baier on Identity & Access Control

Happy DotNetting

In Love with Technology

Knoldus

Knols of experience to your advantage

knowshnet

Search - Read - Request - Share

Rahul's space

Learn, Share and Grow with me !

Dhananjay Kumar

Developer Evangelist @Infragistics | MVP @Microsoft |

SQL Authority with Pinal Dave

SQL Server Performance Tuning Expert

Conficient Blog

Random bits of tech from @conficient

Code! Code! Code!

SOLID & KISS

Code Wala

Designing and coding

Microsoft Mentalist

A way to start with Microsoft Technologies

Tony Sneed's Blog

A glimpse into the lives of Tony & Zuzana Sneed

Sriramjithendra Nidumolu

Personal Notes of Sriramjithendra

%d bloggers like this: