How to: Use wsHttpBinding with Windows Authentication and Message Security in WCF Calling from Windows Forms
Applies to
- Microsoft Windows Communication Foundation (WCF) 3.5
- Windows Forms
- Microsoft Visual Studio 2008
Summary
This how-to article walks you through the process of using Windows authentication over the wsHttpBinding binding type using message security. The article shows you how to configure WCF and test the service with a sample WCF client. This configuration is suited for intranet scenarios where there is a domain controller that will issue Kerberos tickets to provide message protection. There is no need for certificate installation in these scenarios.
Contents
- Objectives
- Overview
- Summary of Steps
- Step 1: Create a Sample WCF Service
- Step 2: Configure the WCF Service to Use wsHttpBinding with Windows Authentication and Message Security
- Step 3: Create a Test Client
- Step 4: Add a WCF Service Reference to the Client
- Step 5: Test the Client and WCF Service
- Additional Considerations
- Deployment Considerations
- Additional Resources
Objectives
- Learn how to create a WCF service hosted in Internet Information Services (IIS).
- Learn how to expose the WCF service with message security.
- Learn how to use Windows tokens to encrypt and sign your messages.
- Learn why you need service principle names (SPNs) and how to create them.
- Learn how to call the service from a test client.
Overview
In the scenario described in this how-to article, users are authenticated by using Windows authentication. This approach is suited for scenarios in which your users have domain credentials. The wsHttpBinding binding is used in order to provide support for message-based security, reliable messaging, and transactions, while also allowing the possibility that legacy clients can consume the service. Message security is used to encrypt and sign your messages while allowing for intermediaries to re-route your message as needed. In general, you should always use WCF transport security unless you need the additional flexibility that message security affords. The scenario described in this How To article uses a Kerberos ticket and a domain controller as the broker for authentication. This mechanism avoids the need for certificates that would otherwise be required for message protection.
Message security is used instead of transport security in order to support:
- Partial encryption of the message.
- Message security that extends beyond a single point-to-point communication channel.
- Flexibility to use other transports such as Transmission Control Protocol (TCP) or named pipes.
Summary of Steps
- Step 1: Create a Sample WCF Service
- Step 2: Configure the WCF Service to Use wsHttpBinding with Windows Authentication and Message Security
- Step 3: Create a Test Client
- Step 4: Add a WCF Service Reference to the Client
- Step 5: Test the Client and WCF Service
Step 1: Create a Sample WCF Service
In this step, you create a WCF service in Microsoft Visual Studio®, hosted in an IIS virtual directory.
- In Visual Studio, on the File menu, select New Web Site.
- In the New Web Site dialog box, under Templates, select WCF Service. Make sure that the Location is set to Http.
- In the New Web Site dialog box, set the new Web site address as https://localhost/ WCFTestService and then click OK.
Step 2: Configure the WCF Service to Use wsHttpBinding with Windows Authentication and Message Security
By default, wsHttpBinding is configured with message security and Windows authentication, so you don't have to actually do anything in this step but verify that your configuration looks as follows:
…
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
…
Note
Remove the <identity> element, which is added automatically, to prevent run-time errors such as “The token provider cannot get tokens for target” when testing with the client application.
Step 3: Create a Test Client
In this step, you create a Windows Forms application to test the WCF service.
- Right-click your solution, click Add, and then click New Project.
- In the Add New Project dialog box, in the Templates section, select Windows Forms Application.
- In the Name field, type Test Client and then click OK.
Step 4: Add a WCF Service Reference to the Client
In this step, you add a reference to your WCF service.
Right-click your client project and then click Add Service Reference.
In the Add Service Reference dialog box, set the URL to your WCF service; for example, https://localhost/WCFTestService/Service.svc.
In the Namespace field, change ServiceReference1 to WCFTestService and then click OK.
Click OK.
A reference to WCFTestService should now appear beneath Service References in your Client project.
Step 5: Test the Client and WCF Service
In this step, you access the WCF service from the client and make sure that it works.
In your client project, drag a button control onto your form.
Double-click the button control to show the underlying code.
In the code behind the button click, create an instance of the proxy and call the GetData operation of your WCF service. The code should look as follows:
private void button1_Click(object sender, EventArgs e) { WCFTestService.ServiceClient myService = new WCFTestService.ServiceClient(); MessageBox.Show(myService.GetData(123)); myService.Close(); }
Right-click the client project and then click Set as Startup Project.
Run the client application by pressing F5 or CTRL+F5. When you click the button on the form, the message “You entered: 123” should appear.
Additional Considerations
By default, negotiateServiceCredentials is set to true, but this can be set to false if you do not support the WS-Trust or WS-SecureConversation specifications. Setting this value to false will also make your service interoperable with Simple Object Access Protocol (SOAP) stacks that implement the Kerberos token profile from OASIS. The following is a configuration sample for setting negotiateServiceCredentials to false:
…
<bindings>
<wsHttpBinding>
<binding name="WsHttpBindingConfig">
<security>
<message negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior"
name="Service">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="WsHttpBindingConfig"
contract="IService">
</endpoint>
</service>
</services>
…
If this property is set to false, the service account must be associated with a service principal name (SPN). To do this, run the service under the Network Service or Local System account. Alternatively, use the SetSpn.exe tool to create an SPN for the service account. In either case, the client must use the correct SPN; you can specify the SPN value in the configuration as follows:
…
<services>
<service behaviorConfiguration="ServiceBehavior"
name="Service">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="WsHttpBindingConfig"
contract="IService">
<identity>
<servicePrincipalName value="Host/<MachineName>" />
</identity>
</endpoint>
</service>
</services>
…
For more information, see MessageSecurityOverHttp.NegotiateServiceCredential Property.
Deployment Considerations
First, make sure that you have a domain controller in the network to authenticate the client and service.
If you are using a custom domain account in the identity pool for your WCF application in IIS, execute the following steps:
Create an SPN for Kerberos to be able to authenticate the client.
By default, “NT AUTHORITY\NETWORK SERVICE” maps to the computer account, so Kerberos works with this account. Go to the domain controller of your domain and create an SPN mapping to the custom domain account. The SPN has the format HTTP/Machinename or HTTP/fullyQualifiedNameofMachine. The examples below show how to create an SPN and map it to the custom domain account myAccount:
- Setspn —a HTTP/machinename myAccount
- Setspn —a HTTP/machinename.code.com myAccount
Give permissions to the domain account to access C:\windows\temp. If this is not done, you will not be able to create a service reference or a proxy client with svcutil.exe. Perform the following steps:
- Open Microsoft Windows® Explorer and navigate to the Windows folder.
- Right-click the Temp directory and then click the Security tab.
- In the user list, click Add and then enter the domain account name in the format domain\accountName.
- Clear all permissions and then click Advanced.
- Double-click the account.
- In the list of permissions, select the List Folder / Read Data and Delete permissions.
Additional Resources
- For more information on Windows authentication, see Explained: Windows Authentication in ASP.NET 2.0.
- For more information on debugging authentication errors, see Debugging Windows Authentication Errors.
- For more information on security authentication best practices, see Best Practices for Security in WCF.
- For additional information on message security, see Message Security in WCF.