How to: Use wsHttpBinding with Username Authentication and TransportWithMessageCredentials in WCF Calling from Windows Forms

patterns & practices Developer Center

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 username authentication over the wsHTTPBinding binding type in order 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 by using 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 the SQL Server Membership Provider
  • Step 2: Grant Access Permission to the WCF Service Process Identity
  • Step 3: Create and Install a 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 the Membership Provider for Username Authentication
  • Step 9: Create a User in the User Store
  • Step 10: Create a Test Client Application
  • Step 11: Add a WCF Service Reference to the Client
  • Step 12: Test the Client and WCF Service
  • Additional Resources

Objectives

  • Learn how to configure the SQL Server membership provider.
  • Learn how to create a WCF service hosted in Internet Information Services (IIS).
  • Learn how to configure the service to use the Secure Sockets Layer (SSL) protocol.
  • Learn how to create and configure a certificate for the service.
  • Learn how to expose the WCF service over wsHttpBinding by using TransportWithMessageSecurity.
  • Learn how to 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 type 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 wsHttpBinding 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 the SQL Server Membership Provider
  • Step 2: Grant Access Permission to the WCF Service Process Identity
  • Step 3: Create and Install a 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 the Membership Provider for Username Authentication
  • Step 9: Create a User in the User Store
  • Step 10: Create a Test Client Application
  • Step 11: Add a WCF Service Reference to the Client
  • Step 12: Test the Client and WCF Service

Step 1: Create a User Store for the SQL Server 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.

To do this, from a Microsoft 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 provider feature. For simple authentication against a SQL Server user store, only the membership provider feature is required.

    For a complete list of the commands, run Aspnet_regsql /?.

Step 2: Grant Access Permission to the 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 aspnet_Membership_FullAccess 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

If you are running on Microsoft Windows® XP, create a SQL Server login for the ASPNET identity instead of the NT Authority\Network Service identity, as the IIS process runs under the ASPNET account in Windows XP.
If you do not have Enterprise Manager or Query Analyzer installed, you can download Microsoft SQL Server Management Studio Express (SSMSE).

Step 3: Create and Install a Service Certificate for Transport Security

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

Creating and installing the certificate is outside the scope of this How To article. For details 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

Temporary certificates should be used for development and testing purposes only. For actual production deployment, get a valid certificate from a certificate authority (CA).

Step 4: Create a Sample WCF Service Project with SSL

In this step, you create a WCF service in Visual Studio and enable SSL.

  1. In Visual Studio, on the File menu, click New Web Site.
  2. In the Templates section, select WCF Service. Make sure that the Location is set to Http and then click Browse.
  3. In the Choose Location dialog box, click Local IIS.
  4. Select the Use Secure Sockets Layer check box at the bottom of the dialog box, and then click Open.
  5. In the New Web Site dialog box, set the new Location to https://localhost/ WCFTestService and then click OK.

Note

The SSL port might not be configured by default in IIS, so it might throw errors while creating the WCF service. To prevent this, open IIS Manager, right-click Default Web Site, and then click Properties. In the Default Web Site Properties dialog box, click the Web Site tab and make sure that the SSL port: is set to 443.

Step 5: Configure the Virtual Directory to Require SSL

In this step, you configure the virtual directory hosting the WCF service to use SSL.

  1. Click Start and then click Run.
  2. In the command line, type inetmgr and then click OK to open the IIS Manager.
  3. In IIS Manager, expand the (local computer) node, expand the Web Sites node, and then expand the Default Web Site node.
  4. Right-click your virtual directory (WCFTestService) and then click Properties.
  5. In the Default Web Site Properties dialog box, on the Directory Security tab, click Edit in the Secure Communications section.
  6. In the Secure communications dialog box, select the Require secure channel (SSL) check box.
  7. In the Secure communications dialog box, click OK.
  8. In the Default Web Site Properties dialog box, click OK.

Step 6: Configure wsHttpBinding for Username Authentication and TransportWithMessageCredential Security

In this step, you configure the WCF service to use username authentication and TransportWithMessageCredentialSecurity.

  1. In the Solution Explorer, right-click the Web.config file of the WCF service and then click Edit WCF Configuration.

    If you do not see the Edit WCF Configuration option, click the Tools menu and then 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, in the Configuration section, expand Service and then expand Endpoints.

  3. Select the first node [Empty Name] and then set the Name attribute to wsHttpEndpoint.

  4. Click the Identity tab and delete the Dns attribute value.

  5. In the Configuration Editor, select the Bindings folder.

  6. In the Bindings section, choose New Binding Configuration.

  7. In the Create a New Binding dialog box, select wsHttpBinding.

  8. Click OK.

  9. Set the Name of the binding configuration to some logical and recognizable name; for example, wsHttpEndpointBinding.

  10. Click the Security tab.

  11. Set the Mode attribute to TransportWithMessageCredential by choosing this option from the drop-down list.

  12. Set the MessageClientCredentialType to UserName by choosing this option from the drop-down list.

  13. Set the TransportClientCredentialType to None by choosing this option from the drop-down list.

  14. In the Configuration section, select the wsHttpEndpoint node.

  15. Set the BindingConfiguration attribute to wsHttpEndpointBinding by choosing this option from the drop-down list.

    This associates the binding configuration setting with the binding.

  16. In the Configuration Editor, on the File menu, click Save.

  17. In Visual Studio, open your configuration and comment out the identity element. It should look as follows:

          <!--<identity>
            <dns value="" />
          </identity>-->
    
  18. 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 endpoint created [Empty Name] and then set the Name attribute to MexHttpsBindingEndpoint.

  3. Set the Binding attribute to mexHttpsBinding by choosing this option from the drop-down list.

  4. In the Configuration Editor, on the File menu, click 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>
    ...
    
  6. In the Configuration Editor, expand the Advanced node, and then expand the Service Behaviors node.

  7. Select the serviceMetadata node.

  8. Set the httpGetEnabled attribute to False and the httpsGetEnabled attribute to True.

  9. In the Configuration Editor, on the File menu, click Save.

  10. 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 the 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>
    
  2. Add a <membership> element inside the <system.web> element as shown in the following example. Notice that 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>
    ...
    
  3. Save the Web.Config file, to ensure that the changes do not get lost during the following steps.

  4. In the Configuration Editor, expand the Advanced node, and then expand the Service Behaviors folder.

  5. Select the ServiceBehavior node.

  6. In the Behavior: ServiceBehavior section, click Add.

  7. In the Adding Behavior Element Extension Sections dialog box, select serviceCredentials and then click Add.

  8. In the Configuration section, under Service Behavior, select serviceCredentials.

  9. Set the UsernamePasswordValidationMode attribute to MembershipProvider by choosing this option from the drop-down list.

  10. Set the MembershipProviderName attribute to MySqlMembershipProvider by choosing this option from the drop-down list.

  11. In the Configuration Editor, on the File menu, click Save.

  12. 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 create a user that the test client will use to log into the WCF service.

  1. In the Solution Explorer, choose the WCF service project, and then on the Website menu, click ASP.NET Configuration.

  2. On the ASP.NET Web Site Administration Tool page, on the Security tab, click the Select authentication type link.

  3. On the page that appears, select the From the internet radio button and then click Done.

  4. Click the Create user link.

  5. On the Create User page, enter the details of the user you want to create in the SQL store and then click Create User.

    If the procedure is successful, a new user will be created. By default, you will need to create a password of at least seven characters, with one character that is not alphanumeric.

Step 10: 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.

Step 11: Add a WCF Service Reference to the Client

In this step, you add a reference to your WCF service to the client.

  1. Right-click your client project and then click 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 then click Go.

  3. In the Namespace field, change ServiceReference1 to WCFService and then click OK.

    A reference to WCFTestService should appear beneath Service References in your client project.

Step 12: Test the Client and WCF Service

In this step, you access the WCF service, pass the user credentials, and make sure that the authentication works through a secure channel (HTTPS).

  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, pass the credentials of the user created in Step 12, and then 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();
    }
    
  4. Right-click the client project and then click Set as Startup Project.

  5. 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 Resources