How To – Use wsHttpBinding with UserName Authentication and TransportWithMessageCredentials in WCF calling 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
  • Microsoft Visual Studio® 2008

Summary

This How To article walks you through the process of using user name Authentication over wsHTTPBinding to authenticate your users against a Microsoft SQL Server Membership Provider. The WCF service in this article will use Transport security with credentials in the message protected with message security. The article shows you how to configure the membership provider, configure WCF, create and install the necessary certificate, and test the service with a sample WCF client.

Contents

  • Objectives
  • Overview
  • Summary of Steps
  • Step 1 – Create a User Store for SQL Membership Provider
  • Step 2 – Grant Access Permission to WCF Service Process Identity
  • Step 3 – Create and Install Service Certificate for Transport Security
  • Step 4 – Create a Sample WCF Service Project with SSL
  • Step 5 – Configure the Virtual Directory to Require SSL
  • Step 6 – Configure wsHttpBinding for Username Authentication and TransportWithMessageCredential Security
  • Step 7 – Configure the Service to Publish Metadata Securely
  • Step 8 – Configure Membership Provider for Username Authentication
  • Step 9 – Create a User in the User Store
  • Step 11 – Create a Test Client Application
  • Step 12 – Add WCF Service Reference to the Client
  • Step 13 – Test the Client and WCF Service
  • Additional Resources

Objectives

  • Configure the SQL Server Membership Provider.
  • Create a WCF service hosted in Internet Information Services (IIS).
  • Configure the service to use the Secure Sockets Layer (SSL) protocol.
  • Create and configure a certificate for the service.
  • Expose the WCF service over wsHttpBinding using TransportWithMessageSecurity.
  • Call the service from a test client.

Overview

Username authentication is suited for scenarios in which your users do not have domain credentials. In the scenario described in this How To article, users are stored in SQL Server and are authenticated against the SQL Server Membership Provider, an identity management system that uses forms authentication. 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. WCF TransportWithMessageCredential security is used to support a secure communication channel in a point-to-point scenario while allowing you to transmit user credentials that are encrypted and protected in the message.

In order to use the SQL Server Membership Provider, you will first create a user store and populate it with your users. You will then configure the store to allow the WCF service access to authenticate users. You will set the clientCredentialType attribute to UserName on the wsHttpBinding binding in order to configure the WCF service to use UserName authentication. You will then install a certificate on the server and configure it for WCF so that messages sent between client and server are encrypted.

Summary of Steps

  • Step 1 – Create a User Store for SQL Membership Provider
  • Step 2 – Grant Access Permission to WCF Service Process Identity
  • Step 3 – Create and Install Service Certificate for Transport Security
  • Step 4 – Create a Sample WCF Service Project with SSL
  • Step 5 – Configure the Virtual Directory to Require SSL
  • Step 6 – Configure wsHttpBinding for Username Authentication and TransportWithMessageCredential Security
  • Step 7 – Configure the Service to Publish Metadata Securely
  • Step 8 – Configure Membership Provider for Username Authentication
  • Step 9 – Create a User in the User Store
  • Step 10 – Create a Test Client Application
  • Step 11 – Add WCF Service Reference to the Client
  • Step 12 – Test the Client and WCF Service

Step 1 – Create a User Store for SQL Membership Provider

The SQL Server Membership Provider stores user information in a SQL Server database. You can create your SQL Server user store manually by using Aspnet_regsql.exe from the command line.

From a Visual Studio 2008 command prompt, run the following command:

aspnet_regsql -S .\SQLExpress -E -A m

In this command:
  • -S specifies the server, which is (.\SQLExpress) in this example.
  • -E specifies to use Windows Authentication to connect to SQL Server.
  • -A m specifies to add only the membership feature. For simple authentication against a SQL Server user store, only the membership feature is required.
  • For a complete list of the commands, run Aspnet_regsql /?

Step 2 – Grant Access Permission to WCF Service Process Identity

Your WCF service process identity requires access to the Aspnetdb database. If you host the WCF Service in Internet Information Services (IIS) 6.0 on Microsoft Windows Server® 2003, the NT AUTHORITY\Network Service account is used by default to run the WCF service.
To grant database access
  1. Create a SQL Server login for NT AUTHORITY\Network Service.
  2. Grant the login access to the Aspnetdb database by creating a database user.
  3. Add the user to the aspnetMembershipFullAccess database role.

You can perform these steps by using the SQL Server Enterprise Manager, or you can run the following script in SQL Query Analyzer.
-- Create a SQL Server login for the Network Service account
sp_grantlogin 'NT AUTHORITY\Network Service'

-- Grant the login access to the membership database
USE aspnetdb
GO
sp_grantdbaccess 'NT AUTHORITY\Network Service', 'Network Service'

-- Add user to database role
USE aspnetdb
GO
sp_addrolemember 'aspnet_Membership_FullAccess', 'Network Service'

Note:

Step 3 – Create and Install Service Certificate for Transport Security

In this step you will create a temporary Service Certificate and install it in the local store. This certificate will be used for establishing an SSL connection between client and the WCF Service.

Creating and installing the certificate is outside the scope of this how to. For steps on how to do this, see How To - Create and Install Temporary Certificates in WCF for Transport Security during Development and follow steps 1 through 4.

Note: Temp certificate should be used for development and testing purposes only, for actual production deployment get a valid certificate from a CA.

Step 4 – Create a Sample WCF Service Project with SSL

In this step you will create a WCF service in Visual Studio and enable SSL.
  1. In the Visual Studio, select File -> New Web Site
  2. In the Templates section select WCF Service. Make sure that the Location is set to Http and then click Browse button.
  3. In the Choose Location dialog box, click Local IIS.
  4. Check the Use Secure Sockets Layer check box at the bottom of the dialog box, and then click Open button.
  5. In the New Web Site dialog box, set the new Web site address as https://localhost/ WCFTestService and then click Ok button.

Note: SSL port might not be configured by default on the IIS, so while creating the WCF service it might throw errors. Open the IIS manager and right click the Default Web Site and choose Properties option. In the Default Web Site Properties dialog box, click the Web Site tab make sure the SSL port: is set to "443".

Step 5 – Configure the Virtual Directory to Require SSL

In this step you will configure the virtual directory hosting the Service to use SSL.
  1. Click Start then Run and in the command box type inetmgr and click OK to open the Internet Information Services manager.
  2. In the Internet Information Services Manager dialog box, expand the (local computer) node, expand the Web Sites node, and then expand the Default Web Site node.
  3. Right click on your virtual directory (WCFTestService) and select Properties.
  4. In the properties dialog box, click on Directory Security tab then click the Edit button** in the* Secure Communication* section.
  5. In the* Secure communications* dialog box, check the Require secure channel (SSL) checkbox.
  6. Click the Ok button in the Secure communications dialog box.
  7. Then click Ok button in the properties dialog box.

Step 6 – Configure wsHttpBinding for Username Authentication and TransportWithMessageCredential Security

In this step you will configure the WCF service to use Username authentication and Transport with Message security.
  1. In the Solution Explorer, right-click the Web.config file of the WCF service and choose the Edit WCF Configuration option.
  2. If you do not see the Edit WCF Configuration option, click the Tools menu and select WCF Service Configuration Editor. Close the WCF Service Configuration Editor tool that appears. The option should now appear on the web.config context menu.
  3. In the configuration editor, in the Configuration section, expand Service and then expand Endpoints.
  4. Select the first node Empty Name. Set the name attribute to wsHttpEndpoint.
  5. Click the Identity tab and delete the Dns attribute value.
  6. In the configuration editor, select the Bindings folder.
  7. In the Bindings section choose New Binding Configuration.
  8. In the Create a New Binding dialog box, select wsHttpBinding.
  9. Click Ok.
  10. Set the Name of the binding configuration to some logical and recognizable name, for example wsHttpEndpointBinding.
  11. Click the Security tab.
  12. Set the Mode attribute to TransportWithMessageCredential, from the drop down.
  13. Set the MessageClientCredentialType to UserName option from the drop down.
  14. Set the TransportClientCredentialType to None option from the drop down.
  15. Select the wsHttpEndpoint node in the configuration section.
  16. Set the BindingConfiguration attribute to wsHttpEndpointBinding from the drop down. This associates the binding configuration setting with the binding.
  17. In the configuration editor dialog, on the File menu, select Save.
  18. In Visual Studio, open your configuration and comment out the identity element. It should look as follows:
<!--<identity>
  <dns value="" />
</identity>-->
  1. In Visual Studio, verify your configuration. The configuration should look as follows:
…
<bindings>
  <wsHttpBinding>
   <binding name="wsHttpEndpointBinding">
          <security mode="*TransportWithMessageCredential*">
            <*transport* clientCredentialType="*None*" />
            <*message* clientCredentialType="*UserName*" />
          </security>
  </binding>
</wsHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="ServiceBehavior" name="Service">
    <endpoint address="" binding="wsHttpBinding"
      *bindingConfiguration="wsHttpEndpointBinding"*
      *name="wsHttpEndpoint"* contract="IService">
**            <!--<identity>
        <dns value="" />
      </identity>-->
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>

Step 7 – Configure the Service to Publish Metadata Securely

In this step, you configure your WCF Service to publish and secure the Metadata. By publishing the Metadata, you will allow your client to add a reference to your WCF Service.
  1. In the configuration editor, expand the Services node, and then expand Endpoints.
  2. Select the second end point created Empty Name and set the Name attribute to MexHttpsBindingEndpoint
  3. Set the Binding attribute to mexHttpsBinding from the drop down.
  4. On the configuration editor dialog, got to File menu and select Save.
  5. In Visual Studio, verify your configuration in Web.config. The configuration should look as follows.
...
<services>
      <service behaviorConfiguration="ServiceBehavior" name="Service">
    		<endpoint address="" binding="wsHttpBinding"
     		 	*bindingConfiguration="wsHttpEndpointBinding"*
      		*name="wsHttpEndpoint"* contract="IService">
   		</endpoint>

        <endpoint address="mex" *binding="mexHttpsBinding"* bindingConfiguration=""
            *name="MexHttpsBindingEndpoint"* contract="IMetadataExchange" />

    </service>
</services>
...
  1. In the configuration editor, expand the Advanced node, and then expand the Service Behaviors and Service Behavior nodes.
  2. Select the serviceMetadata node.
  3. Set the HttpGetEnabled attribute to False and** the* HttpsGetEnabled* attribute to* True*.
  4. On the configuration editor dialog, got to File menu and select Save.
  5. In Visual Studio, verify your configuration in App.config. The configuration should look as follows.
<behaviors>
  <serviceBehaviors>
      <behavior name="ServiceBehavior">
          <serviceMetadata *httpGetEnabled*="*false*" *httpsGetEnabled*="*true*" />
          <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
  </serviceBehaviors>
</behaviors>

Step 8 – Configure Membership Provider for Username Authentication

In this step you configure the SQL Server Membership Provider to use Username authentication.
  1. In the web.config file, replace the existing single <connectionStrings/> element with the following to point to your membership database.
<connectionStrings>
  <add name="MyLocalSQLServer"
       connectionString="Initial Catalog=aspnetdb;
      data source=.\sqlexpress;Integrated Security=SSPI;" />
</connectionStrings>
  1. Add a <membership> element inside the <system.web> element as shown in the following example. Note the use of the <clear/> element prevents the default provider from being loaded and then never used.
...
<system.web>
  ...
  <membership defaultProvider="MySqlMembershipProvider" >
    <providers>
      <clear/>
      <add name="MySqlMembershipProvider"
           connectionStringName="MyLocalSQLServer"
           applicationName="MyAppName"
           type="System.Web.Security.SqlMembershipProvider" />
    </providers>
  </membership>
</system.web>
...
  1. Save the Web.Config file, to ensure the changes do not get lost during the following steps.
  2. In the configuration editor, expand the Advanced node, then expand the Service Behaviors folder.
  3. Select the* ServiceBehavior* node.
  4. In the Behavior: ServiceBehavior section, click the Add button.
  5. In the Adding Behavior Element Extension Sections dialog box select serviceCredentials and click Add button.
  6. In the Configuration section select serviceCredentials option, under Service Behavior.
  7. Set the UsernamePasswordValidationMode attribute to MembershipProvider choosing from the drop down.
  8. Set the MembershipProviderName attribute to MySqlMembershipProvider.
  9. On the configuration editor dialog, go to the File menu and select Save.
  10. In Visual Studio, verify your configuration. The configuration should look as follows.
…
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
           <serviceMetadata *httpGetEnabled*="*false*" *httpsGetEnabled*="*true*" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceCredentials>
        <userNameAuthentication *userNamePasswordValidationMode="MembershipProvider"*
          *membershipProviderName="MySqlMembershipProvider"* />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>
…

Step 9 – Create a User in the User Store

In this step you will create a user that the test client will use to log into the service.
  1. In the solution explorer, choose the WCF service project, and from the Website menu select ASP.NET Configuration.
  2. In the ASP.NET Web Site Administration Tool page, select the Security tab, and click the Select authentication type link.
  3. On the page displayed select the From the internet radio button and click the Done button.
  4. Then click the Create user link.
  5. In the Create User page give the details of the user you want to create in the SQL store and click the Create User button. If successful it will create a new user. By default you’ll need to create a password of at least seven characters with one character that is not alpha or numeric.

Step 10 – Create a Test Client Application

In this step, create a Windows Form application to test WCF Service.
  1. Right-click your Solution, click Add and then click New Project.
  2. In the Add New Project dialog box, select Windows Forms Application from the Templates section.
  3. In the Name field, type Test Client and click Ok button.

Step 11 – Add WCF Service Reference to the Client

In this step, you add a reference to your WCF Service.
  1. Right-click your Client project and select Add Service Reference.
  2. In the Add Service Reference dialog box, set the URL to your WCF Service, for example https://localhost/WCFTestService/Service.svc and click Go.
  3. In the Namespace field, change ServiceReference1 to WCFService and Click Ok.
  4. In your Client project, a reference to WCFTestService should appear beneath Service References.

Step 12 – Test the Client and WCF Service

In this step you access the WCF Service and pass the user credentials and make sure the authentication works through a Secure channel (HTTPS).
  1. In your Client project, drag a Button control to your Form.
  2. Double-click the Button control to show the code behind.
  3. Create an instance of the proxy, pass the credentials of the user created in step 12, 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();
      myService.ClientCredentials.UserName.UserName = "username";
      myService.ClientCredentials.UserName.Password = "p@ssw0rd";
      MessageBox.Show(myService.GetData(123));
      myService.Close();
}
  1. Right click on the Client project and select Set as Startup Project.
  2. Run the Client application using F5 or Ctrl+F5, when you click the Button on the form it should display a message “You entered: 123

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 10:34 PM by prashantbansode, version 1

Comments

No comments yet.