How To: Use netTcpBinding with Windows Authentication and Message Security in WCF from Windows Forms

- J.D. Meier, Jason Taylor, Prashant Bansode, Carlos Farre, Madhu Sundararajan, Steve Gregersen

Applies To

  • Microsoft® Windows Communication Foundation (WCF) 3.5
  • Windows Forms
  • Microsoft Visual Studio® 2008

Summary

This how to shows you how to use the netTcpBinding with Windows Authentication and Message security. NetTcpBinding is used for communicating with WCF clients in an intranet and provides transport security with windows authentication by default. This how to shows you how to configure the service to use message security instead of transport security. In this how to, the WCF service is hosted in a Windows service.

Contents

  • Objectives
  • Overview
  • Summary of Steps
  • Step 1 – Create a Windows Service
  • Step 2 – Create a Sample WCF Service
  • Step 3 – Modify the Windows Service to Host the WCF Service
  • Step 4 – Configure the WCF Service to Use netTcpBinding with Message Security
  • Step 5 – Configure the WCF Service to Publish Metadata
  • Step 6 – Install the Windows Service
  • Step 7 – Create a Test Client Application
  • Step 8 – Test the Client and WCF Service
  • Additional Resources

Objectives

  • Create a WCF service hosted in a Windows service.
  • Learn how to expose the WCF service with message security.
  • Learn how to use Windows tokens for encrypting and signing your messages.
  • Learn why you need service principle names (SPNs) and how to create them

Overview

Windows Authentication is suited for scenarios in which your users have domain credentials. In the scenario described in this How To article, users are authenticated by Windows Authentication. The scenario described in this How To article uses the netTcpBinding binding to expose a WCF service to WCF-enabled clients. The netTcpBinding binding offers improved performance over an HTTP binding. In this scenario WCF is hosted in a Windows service. The WCF service with netTcpBinding can be consumed by a WCF-enabled .NET application through the use of a service reference. The Visual Studio service reference generates a proxy class to abstract the underlying message-based communication. WCF message security is used to support a secure communication channel in a end-to-end scenario. In general, you should always use transport security unless you need the additional flexibility that message security affords you. For example, you would use message security for scenarios in which there are intermediaries who need to inspect and re-route the message.

In this How To, you will create a Windows service to host your WCF service. You will then create sample WCF service in Visual Studio 2008 and configure the service to use netTcpBinding with message security through the use of the WCF Configuration Editor. Next, you will configure a mexTcpBinding so that the service can expose its metadata to clients from which they can generate a WCF proxy and call your service. Finally, you will create a test client to verify that the service is working properly.
Solution Summary
  • Binding: By default, netTcpBinding offers improved performance over an HTTP binding and is the ideal choice for cross machine communication between WCF clients and a WCF service, in an intranet.
  • Security Mode: Transport security is the default security mode for netTcpBinding and should be preferred over Message security for better performance. If needed, message security can provide greater control over signing and encryption of the message.
  • Client Authentication: Since this binding is used inside an intranet, Windows is the recommended client authentication mechanism though the default is UserName. The other possible values are None, Certificate and IssuedToken.
  • Algorithm Suite: The default message encryption algorithm used is Basic256 and should suffice for most scenarios. A stronger encryption algorithm can be chosen for increased security.
  • Hosting Consideration: This how-to hosts WCF in a Windows service. In general, netTcpBinding services can be hosted in a windows service, IIS 7.0 (not IIS 6.0 or lower), WAS or can be self-hosted. The choice should be based on the deployment requirements of the service.

Summary of Steps

  • Step 1 – Create a Windows Service
  • Step 2 – Create a Sample WCF Service
  • Step 3 – Modify the Windows Service to Host the WCF Service
  • Step 4 – Configure the WCF Service to Use netTcpBinding with Message Security
  • Step 5 – Configure the WCF Service to Publish Metadata
  • Step 6 – Install the Windows Service
  • Step 7 – Create a Test Client Application
  • Step 8 – Test the Client and WCF Service

Step 1 – Create a Windows Service

In this step, you create a Windows service to host your WCF service.
  1. In Visual Studio, on the File menu, click New and then click Project.
  2. In the New Project dialog box, in the Project Types section, select Windows under Visual C#.
  3. In the Templates section, select Windows Service, and type the name of your project (WCFServiceHost) in the Name field.
  4. In the Add a Project dialog box, click OK to add a sample Windows service to the solution.
  5. Right-click Service1.cs and then click View Designer.
  6. Right-click the designer and then click Add Installer to add the ProjectInstaller.cs file with two objects, serviceProcessInstaller1 and serviceInstaller1.
  7. In the designer view of ProjectInstaller.cs, right-click serviceProcessInstaller1 and then click Properties.
  8. In the Properties pane, set the Account attribute to NetworkService.
This will run your Windows service under the Network Service account.

Step 2 – Create a Sample WCF Service

In this step, you add a WCF service to the Windows service that will host it.
  1. Right-click the Windows service project, click Add, and then click New Item.
  2. In the Add New Item dialog box, select WCF Service.
  3. Set the Name as MyService.cs and then click the Add.
Note that the configuration file, App.config, gets added automatically.
  1. Modify the DoWork() method signature in IMyService.cs to accept a string parameter and return a string data type as shown below:
string DoWork(string value);
  1. Modify the DoWork() method in MyService.cs to accept a string parameter and return a string data type as below.
public string DoWork(string value)
{
      return "Welcome " + value;
}

Step 3 – Modify the Windows Service to Host the WCF Service

In this step, you add code to the OnStart() and OnStop() methods to start and stop the WCF Service inside the Windows service process.
  1. In the Solution Explorer, right-click Service1.cs and then click View Code.
  2. In the Service1.cs file, add a using statement as follows:
using System.ServiceModel;
  1. Declare an internal static member of ServiceHost type as follows:
internal static ServiceHost myServiceHost = null; 
  1. Add code to the OnStart method of the Windows service, to open the service:
protected override void OnStart(string[] args)
{
   if (myServiceHost != null)
   {
       myServiceHost.Close();
   }

   myServiceHost = new ServiceHost(typeof(MyService));
   myServiceHost.Open();
}
  1. Add code to the OnStop method of the Windows service, to close the service host
protected override void OnStop()
{
   if (myServiceHost != null)
   {
      myServiceHost.Close();
      myServiceHost = null;
   }
}
  1. Build the solution and verify that your project produces WCFServiceHost.exe in your project \bin directory.

Step 4 – Configure the WCF Service to Use netTcpBinding with Message Security

In this step, you configure your WCF service to use netTcpBinding and message security.
  1. In the Solution Explorer, Right-click the App.config file and then click Edit WCF Configuration. If you do not see the Edit WCF Configuration option, on the Tools menu, click WCF Service Configuration Editor. Close the WCF Service Configuration Editor tool that appears. The option should now appear on the web.config context menu.
  2. In the Configuration Editor, expand the Services node and then expand WCFHostService.MyService.
  3. Select the Host node, select the default BaseAddress in the Base addresses section, and then click Delete.
  4. Click New and then in the Base Address Editor dialog box, set the Base address: to net.tcp://localhost:8523/WCFTestService.
  5. Expand the* Endpoints* node, select the first Empty Name node, and then set the set the Name attribute to NetTcpBindingEndpoint.
  6. Set the* Binding* attribute to netTcpBinding.
  7. In the Configuration Editor dialog box, on the File menu, select Save.
  8. In Visual Studio, verify the configuration in your App.config, which should look as follows:
<services>
    <service behaviorConfiguration="WCFHostService.MyServiceBehavior"
        name="WCFHostService.MyService">
        <endpoint address="" *binding="netTcpBinding"*
               bindingConfiguration=""
               *name="NetTcpBindingEndpoint"*
               contract="WCFHostService.IMyService">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding"
                  contract="IMetadataExchange" />
        <host>
            <baseAddresses>
                <add *baseAddress="net.tcp://localhost:8523/WCFTestService"* />
            </baseAddresses>
        </host>
    </service>
</services>
  1. In the Configuration Editor, select the Bindings node and then click the New Binding Configuration link.
  2. In the Create a New Binding dialog box, select netTcpBinding and then click OK.
  3. Set the Name attribute to NetTcpBindingEndpointConfig on the newly created biding configuration.
  4. Click the Security tab and then set the Mode attribute to Message.
  5. Verify that the MessageClientCredentials attribute is set to Windows.
  6. In the NetTcpBindingEndpoint binding created above, set the BindingConfiguration to NetTcpBindingEndpointConfig by selecting it from the dropdown.
  7. In the Configuration Editor dialog box, on the File menu, select Save.
  8. In Visual Studio, verify your configuration, which should look as follows:
...
<bindings>
    <netTcpBinding>
        <binding *name="NetTcpBindingEndpointConfig"*>
            <security *mode="Message"* />
        </binding>
    </netTcpBinding>
</bindings>
...
<services>
    <service behaviorConfiguration="WCFHostService.MyServiceBehavior"
        name="WCFHostService.MyService">
        <endpoint address="" binding="netTcpBinding"
                   *bindingConfiguration="NetTcpBindingEndpointConfig"*
                   name="NetTcpBindingEndpoint" contract="WCFHostService.IMyService">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
            contract="IMetadataExchange" />
        <host>
            <baseAddresses>
                <add baseAddress="net.tcp://localhost:8523/WCFTestService" />
            </baseAddresses>
        </host>
    </service>
</services>
...

Step 5 – Configure the WCF Service to Publish Metadata

In this step, you configure your WCF service to publish metadata. Publishing the metadata will allow your client to add a reference to the WCF service.
  1. In the Configuration Editor, expand the Services node and then expand the WCFHostService.MyService node.
  2. Expand the Endpoints node, select the remaining Empty Name node, and then set the Name attribute to mexTcpBindingEndpoint.
  3. Set the Binding attribute to mexTcpBinding.
  4. In the Configuration Editor dialog box, on the File menu, select Save.
  5. In Visual Studio, verify the configuration in your App.config file. The configuration should look as follows:
...
<services>
    <service behaviorConfiguration="WCFHostService.MyServiceBehavior"
        name="WCFHostService.MyService">
        <endpoint address="" binding="netTcpBinding"
                      bindingConfiguration="NetTcpBindingEndpointConfig"
                  name="NetTcpBindingEndpoint" contract="WCFHostService.IMyService">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
        <endpoint address="mex" *binding="mexTcpBinding"* bindingConfiguration=""
            *name="mexTcpBindingEndpoint"* contract="IMetadataExchange" />
        <host>
            <baseAddresses>                <add baseAddress="net.tcp://localhost:8523/WCFTestService" />
            </baseAddresses>
        </host>
    </service>
</services>
...
  1. In the Configuration Editor, expand the Advanced node and then expand the Service Behaviors node.
  2. Expand the WCFHostService.MyServiceBehavior node and then select the serviceMetadata node.
  3. Set the HttpGetEnabled attribute to False.
  4. In the Configuration Editor dialog box, on the File menu, select Save.
  5. In Visual Studio, verify the configuration in your App.config file. The configuration should look as follows:
<behaviors>
    <serviceBehaviors>
        <behavior name="WCFHostService.MyServiceBehavior">
            <serviceMetadata *httpGetEnabled="false"* />
            <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
    </serviceBehaviors>
</behaviors>

Step 6 – Install the Windows Service

In this step, you install the Windows service and run it from the Services console.
  1. Rebuild the solution and open a Visual Studio command prompt.
  2. Navigate to the bin directory of the project where WCFServiceHost.exe was copied.
  3. On the command line, execute the following command to install the service:

Installutil WCFServiceHost.exe
  1. After the service has installed successfully, open the services console by executing services.msc on the command line.
  2. In the services console, search for the name of the service, Service1, and start it.

Note: If you have modified the service that is already installed, you can uninstall it by using following command:

Installutil /u WCFServiceHost.exe

Step 7 – Create a Test Client Application

In this step, you create a Windows Forms application to test the WCF service.
  1. Right-click your solution, click Add, and then click New Project.
  2. In the Add New Project dialog box, in the Templates section, select Windows Forms Application.
  3. In the Name field, type Test Client and then click OK.
  4. Right-click your client project and then click Add Service Reference.
  5. In the Add Service Reference dialog box, set the Service URI: to net.tcp://localhost:8523/WCFTestService and then click Go.
  6. Set the Service reference name: to WCFTestService and then click OK.

Step 8 – Test the Client and WCF Service

In this step, you use the test client to ensure that the WCF service is running properly.
  1. In your Client project, drag a button control onto your form.
  2. Double-click the button control to show the underlying code.
  3. Create an instance of the proxy and call the DoWork method on your WCF service.
When you call the service, your current user security context will automatically be passed to your WCF service. The code should look as follows:
private void button1_Click(object sender, EventArgs e)
{
      WCFTestService.MyServiceClient myService = new
                             WCFTestService.MyServiceClient();
      MessageBox.Show(myService.DoWork("Hello World!"));
      myService.Close();
}
  1. Right-click the client project and then click Set as Startup Project.
  2. Run the client application by pressing F5 or Ctrl+F5.
When you click the button on the form, it should display the message “Welcome Hello World!”.

Additional Resources

Contributors and Reviewers

  • External Contributors and Reviewers:
  • Microsoft Consulting Services and PSS Contributors and Reviewers:
  • Test team: Rohit Sharma, Chaitanya Bijwe, Parameswaran Vaideeswaran.
  • Edit team: Dennis Rea.
  • SEO team: Rob Boucher.

Last edited Apr 30, 2008 at 9:19 PM by prashantbansode, version 1

Comments

sdahlbac Dec 8, 2009 at 7:13 AM 
If one of the objectives for this article is "Learn why you need service principle names (SPNs) and how to create them " then it's a fail, nowhere do I see them mentioned, in addition, NetworkService accont is used and not custom account.