Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Part 47 - WCF security

Suggested Videos
Part 44 - Multiple concurrency mode in WCF
Part 45 - Reentrant concurrency mode in WCF
Part 46 - WCF throttling



In this video we will discuss the basics of WCF security



First let's understand some of the fundamental security terms
Authentication - The process of identifying the sender and recipient of the message.

Authorization - The process of determining what rights the authenticated user has.

Confidentiality - The process of ensuring that only the intended recipient of the message can view the message as it is being transmitted from the sender to the receiver. We achieve confidentiality by encrypting the message.

Integrity - The process of ensuring that the message is not tampered with by a malicious user as it is being transmitted from the sender to the receiver. We achieve Integrity by signing the messages.

Bindings in WCF determine the security scheme. The following MSDN link contains all the system provided bindings and their respective security defaults.
http://msdn.microsoft.com/en-us/library/ms731092(v=vs.110).aspx

Notice that the default security scheme for NetTcpBinding is Transport and for WSHttpBinding it is Message. First let's understand the difference between Message security and Transport security.
From a security perspective, when sending a message between a client and a WCF service, there are 2 things to consider
1. The WCF Message itself
2. The medium or protocol (HTTP, TCP, MSMQ) over which the message is sent

Securing the transport channel is called transport security. Each of the protocols (HTTP, TCP, MSMQ etc) have their own way of providing transport security. For example, TCP provides transport security, by implementing Transport Layer Security (TLS). The TLS implementation is provided by the operating system. HTTP provides transport security by using Secure Sockets Layer (SSL) over HTTP. Transport security provides only point-to-point channel security. It means if there is an intermediary (Load balancer, proxy etc) between, then that intermediary has direct access to content of the message.

Securing the message itself by encapsulating the security credentials with every SOAP message is called message security. As the message itself is protected, it provides end to end security.

The following MSDN article explains all the differences between message and transport security and when to use one over the other.
http://msdn.microsoft.com/en-us/library/ms733137.aspx

By default for secure bindings WCF messages are signed and encrypted. Let's understand this with an example.
Step 1: Create a class library project with name = HelloService. Delete the autogenerated class1.cs file.

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

Step 3: Copy and paste the following code in IHellotService.cs file
using System.ServiceModel;

namespace HelloService
{
    [ServiceContract]
    public interface IHelloService
    {
        [OperationContract]
        string GetMessage(string message);
    }
}

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

Step 5: Right click on HelloService 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 HelloService 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" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="mexBehavior"
               name="HelloService.HelloService">
        <endpoint address="HelloService"
                  binding="wsHttpBinding"
                  contract="HelloService.IHelloService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Step 9: Copy and paste the following code in Program.cs file in the Host project.
using System.ServiceModel;
using System;

namespace Host
{
    class Program
    {
        public static void Main()
        {
            using (ServiceHost host = new ServiceHost(typeof(HelloService.HelloService)))
            {
                host.Open();
                Console.WriteLine("Host started @ " + DateTime.Now.ToString());
                Console.ReadLine();
            }
        }
    }
}

Step 10: 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 11: Now let's create a client for the WCF service. Create a new windows forms application with name = WindowsClient

Step 12: Add a service reference to HelloService. 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 HelloService. In the Namespace textbox type HelloService and click OK.

Step 13: Drag and drop a button and a textbox control on Form1. Set the following properties on button1
Name = btnGetMessage
Text  = Get Message

Step 14: 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 WindowsClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnGetMessage_Click(object sender, EventArgs e)
        {
            HelloService.HelloServiceClient client =
                new HelloService.HelloServiceClient();
            MessageBox.Show(client.GetMessage(textBox1.Text));
        }
    }
}

In this example we are using wsHttpBinding. With wsHttpBinding by default, the SOAP message body is Encrypted and Signed. To view the Encrypted and Signed message enable message logging for the WCF Service. We discussed enabling message logging in Part 9 of the WCF tutorial.

In the WCF Service config file change security mode to None as shown below.
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp">
      <security mode="None">
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Note: Please don't forget to associate binding configuration with the endpoint using bindingConfiguration attribute as shown below.
<endpoint address="HelloService"
          binding="wsHttpBinding"
          contract="HelloService.IHelloService"
          bindingConfiguration="wsHttp"/>

Run the WCF service and the client and notice that the logged message is in plain text, that is the message is not encrypted and signed.

wcf tutorial

1 comment:

  1. You need to add a base address of https as per VS 2015 -
    Additional information: Could not find a base address that matches scheme https for the endpoint with binding WSHttpBinding. Registered base address schemes are [http].

    ReplyDelete

It would be great if you can help share these free resources