How to: Use Username Authentication with the SQL Server Membership Provider and Message Security in WCF from Windows Forms

patterns & practices Developer Center

Applies to

  • Microsoft Windows Communication Foundation (WCF) 3.5
  • Microsoft Visual Studio 2008
  • Microsoft SQL Server

Summary

This how-to article walks you through the process of using username authentication over the wsHttpBinding binding to authenticate your users against a Microsoft SQL Server® membership provider. 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 a Sample WCF Service
  • Step 4: Configure wsHttpBinding with Username Authentication and Message Security
  • Step 5: Configure the Membership Provider for Username Authentication
  • Step 6: Create and Install a Service Certificate
  • Step 7: Configure the Service Certificate for WCF
  • Step 8: Create a User in the User Store
  • Step 9: Create a Test Client
  • Step 10: Add a WCF Service Reference to the Client
  • Step 11: 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 Microsoft Internet Information Services (IIS).
  • Learn how to create and configure a certificate for the service.
  • 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 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 message security is used to support the scenario in which there may be intermediaries inspecting the message before final delivery. In general, you should always use transport security unless you need the additional flexibility that message security affords.

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. For test purposes, you will set the revocationMode attribute to NoCheck so that the temporary test certificate works properly.

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 a Sample WCF Service
  • Step 4: Configure wsHttpBinding with Username Authentication and Message Security
  • Step 5: Configure the Membership Provider for Username Authentication
  • Step 6: Create and Install a Service Certificate
  • Step 7: Configure the Service Certificate for WCF
  • Step 8: Create a User in the User Store
  • Step 9: Create a Test Client
  • Step 10: Add a WCF Service Reference to the Client
  • Step 11: 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.

  • 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 feature. For simple authentication against a SQL Server user store, only the membership feature is required.

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

Notes:
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, you can download Microsoft SQL Server Management Studio Express (SSMSE).

Step 3: Create a Sample WCF Service

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

  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 specify the virtual directory to be created in the Path (e.g., https://localhost/WCFTestService).

  3. In the New Web Site dialog box, click OK to create a virtual directory and a sample WCF service.

  4. Browse to your WCF service (i.e., https://localhost/WCFTestService/Service.svc).

    You should see details of your WCF service.

Step 4: Configure wsHttpBinding with Username Authentication and Message Security

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

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

    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.

  2. In the Configuration Editor, in the Configuration section, expand Service and then expand Endpoints.

  3. Select the first node [Empty Name]. Set the name attribute to wsHttpEndpoint.

    By default, the name field will be empty because it is an optional attribute.

  4. Click the Identity tab and then 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. Make sure that the Mode attribute is set to Message, which is the default setting.

  12. Set the MessageClientCredentialType to the Username option by selecting this option from the drop-down list.

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

  14. Set the BindingConfiguration attribute to wsHttpEndpointBinding by selecting this option from the drop-down list.

    This associates the binding configuration setting with the binding.

  15. In the Configuration Editor dialog box, on the File menu, click Save.

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

          <!--<identity>
            <dns value="" />
          </identity>-->
    
  17. In Visual Studio, verify your configuration. The configuration should look as follows:

    …
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security>
            <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 5: 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. Note that the use of the <clear/> element prevents the default provider from being loaded and 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 default behavior that was created. Its name will be ServiceBehavior.

  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 Behaviors, select the serviceCredentials option.

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

  10. Set the MembershipProviderName attribute to MySqlMembershipProvider.

  11. In the Configuration Editor dialog box, on the File menu, select Save.

  12. In Visual Studio, verify your configuration. The configuration should look as follows:

    …
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="MySqlMembershipProvider" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    …
    

Step 6: Create and Install a Service Certificate

In this step, you create a temporary service certificate and install it in the local store. This certificate will be used to encrypt the message, protecting the username and password as well as any other sensitive data.

Creating and installing the certificate is outside the scope of this How To article. For detailed steps on how to do this, see How to: Create and Install Temporary Certificates in WCF for Message Security During Development.

Note

Notes:
If you are running on Windows XP, give the certificate permissions for the ASPNET identity instead of the NT Authority\Network Service identity because the IIS process runs under the ASPNET account in Windows XP.
Temp certificate should be used for development and testing purposes only. For actual production deployment, you will need to get a valid certificate from a certificate authority (CA).

Step 7: Configure the Service Certificate for WCF

In this step, you configure WCF to use the temporary certificate you created in the previous step.

  1. In the Configuration Editor, expand the Advanced node, expand the ServiceBehaviors and ServiceBehavior nodes, and then expand the serviceCredentials node.

  2. Select the serviceCertificate node and set the FindValue attribute to the subject name of the certificate you are going to use; for example, "CN=tempCert".

  3. In the Configuration Editor dialog box, on the File menu, click Save.

  4. In Visual Studio, verify your configuration. The configuration should look as follows:

    ...
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <serviceCertificate findValue="CN=tempCert" />
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="MySqlMembershipProvider" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    ...
    

Step 8: 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 then on the Website menu, select ASP.NET Configuration.

  2. On the ASP.NET Web Site Administration Tool page, click the Security tab, and then 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 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 9: Create a Test Client

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 10: Add a WCF Web Reference to the Client

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

  1. Right-click your Client project and select Add Web Reference.

  2. In the Add Web Reference dialog box, set the URL to your WCF service (e.g., https://localhost/WCFTestService/Service.svc) and then click Go.

  3. In the Web reference name field, change ServiceReference1 to WCFTestService.

  4. Click Add Reference.

    In your Client project, a reference to WCFTestService should now appear beneath Web References.

Step 11: Test the Client and WCF Service

In this step, you access the WCF service, pass the user credentials, and make sure that the username authentication works.

  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 8, 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 select Set as Startup Project.

  5. Run the Client application by pressing F5 or CTRL+F5.

    When you click the button on the form, it should display the message “You entered: 123”.

Additional Resources