Saturday, September 7, 2019

Configure netTcpBinding to use message security

We will discuss configuring netTcpBinding to use message security mode instead of transport security which is the default.



The following MSDN article contains all the system provided bindings and their security defaults. Notice that the default for netTcpBinding is Transport security.
http://msdn.microsoft.com/en-us/library/ms731092(v=vs.110).aspx

Here are the steps to configure netTcpBinding to use message security instead of  transport security.
Step 1: Create a class library project with name = SimpleService. Delete the auto-generated class1.cs file.

Step 2: Right click on SimpleService project in solution explorer and add a WCF service with name = SimpleService

Step 3: Copy and paste the following code in ISimpleService.cs file
using System.ServiceModel;
namespace SimpleService
{
    [ServiceContract]
    public interface ISimpleService
    {
        [OperationContract]
        string GetMessage(string name);
    }
}

Step 4: Copy and paste the following code in SimpleService.cs file
namespace SimpleService
{
    public class SimpleService : ISimpleService
    {
        public string GetMessage(string name)
        {
            return "Hello " + name;
        }
    }
}

Step 5: Now, let's host the WCF service using a Console application. Right click on SimpleService solution in solution explorer and add a console project with name = Host. We will use this project to host the WCF service.

Step 6: Right click on References folder under Host project and add a reference to SimpleService project and System.ServiceModel assembly.


Step 7:  Right click on Host project and add Application Configuration file. This should add App.config file.

Step 8: Copy and paste the following configuration in App.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="mexBehavior" name="SimpleService.SimpleService">
        <endpoint address="SimpleService" binding="netTcpBinding"
                  contract="SimpleService.ISimpleService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
            <add baseAddress="net.tcp://localhost:8090" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Step 9: Enable message logging for the WCF Service. We discussed this in detail in Part 9 of WCF tutorial.

Step 10: Copy and paste the following code in Program.cs file in the Host project.
using System;
using System.ServiceModel;
namespace Host
{
    class Program
    {
        public static void Main()
        {
            using (ServiceHost host = new ServiceHost(typeof(SimpleService.SimpleService)))
            {
                host.Open();
                Console.WriteLine("Host started @ " + DateTime.Now.ToString());
                Console.ReadLine();
            }
        }
    }
}

Step 11: Set Host project as the startup project and run the application by pressing CTRL + F5 key. At this point we have the WCF service up and running.

Step 12: Now let's create a client for the WCF service. Create a new windows forms application with name = Client

Step 13: Add a service reference to SimpleService. Right click on References folder and select Add Service Reference. In the Add Service Reference window type Address = http://localhost:8080/ and click GO button. This should bring up the SimpleService. In the Namespace textbox type SimpleService and click OK. 

Step 14: Drag and drop a button and a textbox control on Form1. Set the following properties on button1
Name = btnCallService
Text  = Call Service

Step 15: Double click on the button to generate the "click event handler" method. Copy and paste the following code in Form1.cs file.
using System;
using System.Windows.Forms;

namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnCallService_Click(object senderEventArgs e)
        {
            SimpleService.SimpleServiceClient client = new SimpleService.SimpleServiceClient();
            MessageBox.Show(client.GetMessage("Pragim"));
        }
    }
}

Step 16: Run the client application. Click the button to invoke the service. Inspect the logged messages and notice that the body of the SOAP message is not encrypted, which implies that the default security mode (transport security) of netTcpBinding is being used. Transport security provides message protection(Encryption and Digital signatures) at the transport layer. By the time the message is arrived at the message log it is already decrypted. That is the reason why we see messages in plain text in the log.

Step 17: In app.config file of the Host project, include the following bindings section, to customize the netTcpBinding to use Message security instead of the default transport security.
<bindings>
  <netTcpBinding>
    <binding name="netTcp">
      <security mode="Message"></security>
    </binding>
  </netTcpBinding>
</bindings>

Step 18: Associate the above customization with the service endpoint using bindingConfiguration attribute as shown below.
<endpoint address="SimpleService"
  binding="netTcpBinding"
  contract="SimpleService.ISimpleService"
  bindingConfiguration="netTcp"/>

Step 19: Run the WCF service. In the client application, delete the SimpleService service reference, and then add the service reference again to SimpleService. At this point, notice the configuration in the app.config file of the client application. Notice that instead of the defaults of netTcpBinding, we are now using "Message" security mode.

Step 20: Run the client application, and then click "Call Service" button. We now get the out put as expected.  Inspect the logged messages and notice that the body of the SOAP message is encrypted, which implies that the netTcpBinding is now using Message security.

No comments:

Post a Comment

Get max value for identity column without a table scan

  You can use   IDENT_CURRENT   to look up the last identity value to be inserted, e.g. IDENT_CURRENT( 'MyTable' ) However, be caut...