How To – Use Username Authentication with the SQL Server Membership Provider 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
  • Microsoft Visual Studio® 2008

Summary

This How To article walks you through the process of using username authentication over wsHttpBinding 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 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 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 – Configure the Client to Set RevocationMode to NoCheck
  • Step 12 – Test the Client and WCF Service
  • Additional Resources

Objectives

  • Configure the SQL Server Membership Provider.
  • Create a WCF service hosted in Microsoft Internet Information Services (IIS).
  • Create and configure a certificate for the service.
  • 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 you.

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. 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 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 – Configure the Client to Set RevocationMode to NoCheck
  • 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 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 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 a Sample WCF Service

In this step, you create a WCF service in Visual Studio.
  1. In 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 specify the virtual directory to be created in the Path (e.g.,** http://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., http://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.
  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. By default, the name field will be empty because it is an optional attribute.
  5. Click the Identity tab and then 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. Make sure that the Mode attribute is set to Message, which is the default setting.
  13. Set the MessageClientCredentialType to the Username option by selecting this option from the drop-down list.
  14. In the Configuration section, select the wsHttpEndpoint node.
  15. Set the BindingConfiguration attribute to wsHttpEndpointBinding by selecting this option from the drop-down list. This associates the binding configuration setting with the binding.
  16. In the configuration editor dialog box, on the File menu, select Save.
  17. 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>
        <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 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 that the changes do not get lost during the following steps.
  2. In the configuration editor, expand the Advanced node, and then expand the Service Behaviors folder.
  3. Select the default behavior that was created. Its name will be "ServiceBehavior".
  4. In the Behavior: ServiceBehavior section, click Add.
  5. In the Adding Behavior Element Extension Sections dialog box, select serviceCredentials and then click Add.
  6. In the Configuration section, and then under Service Behaviors, select the serviceCredentials option.
  7. Set the UsernamePasswordValidationMode attribute to MembershipProvider by choosing this option from the drop-down list.
  8. Set the MembershipProviderName attribute to MySqlMembershipProvider.
  9. In the configuration editor dialog box, on the File menu, select Save.
  10. 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:
  • 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, select 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 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 (e.g., http://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 – Configure the Client to Set RevocationMode to NoCheck

In this step, you configure the client to not check revocation status on the temporary certificate.
  1. In your test client, right-click the App.config file in the Solution Explorer and then select Edit WCF Configuration.
  2. In the configuration editor, expand the Advanced node, select Endpoint Behaviors, and then select New Endpoint Behavior Configuration.
  3. Click Add.
  4. In the Adding Behavior Element Extension Sections dialog box, select clientCredentials and then click Add.
  5. Expand the clientCredentials node, expand the serviceCertificate node, and then select authentication below it.
  6. Set the RevocationMode attribute to NoCheck by choosing this option from the drop-down list.
  7. In the configuration editor, expand the Client node, expand the Endpoints node, and then select the WsHttpEndpoint node.
  8. Set the BehaviorConfiguration attribute to NewBehavior by choosing this option from the drop-down list. This is the endpoint behavior you just created.
  9. In the configuration editor dialog box, on the File menu, select Save.
  10. In Visual Studio, verify your configuration. The configuration should look as follows:
…
<behaviors>
    <endpointBehaviors>
        <behavior *name="NewBehavior"*>
            <clientCredentials>
                <serviceCertificate>
                    <authentication *revocationMode="NoCheck"* />
                </serviceCertificate>
            </clientCredentials>
        </behavior>
    </endpointBehaviors>
</behaviors>
      <bindings>
          <wsHttpBinding>
              <binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
                  receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                  transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                  maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                  messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                  allowCookies="false">
                  <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                  <reliableSession ordered="true" inactivityTimeout="00:10:00"
                      enabled="false" />
                  <security mode="Message">
                      <transport clientCredentialType="Windows" proxyCredentialType="None"
                          realm="" />
                      <message clientCredentialType="UserName" negotiateServiceCredential="true"
                          algorithmSuite="Default" establishSecurityContext="true" />
                  </security>
              </binding>
          </wsHttpBinding>
</bindings> 
<client>
    <endpoint address="http://<<fully qualified machine name>>/WCFTestService/Service.svc"
        *behaviorConfiguration="NewBehavior"* binding="wsHttpBinding"
        bindingConfiguration="wsHttpEndpoint" contract="WCFTestService.IService"
        name="wsHttpEndpoint">
        <identity>
            <certificate encodedValue="SomeEncodeValue" />
        </identity>
    </endpoint>
</client>
…

Important: This should be done in development only, when using the makecert utility for creating the certificates. In a real-world production environment, you would not overwrite the revocationMode settings.

Note: If you have your client application on a separate machine, you will have to install the Root Authority certificate created in Step 6 on your client machine as well.

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 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();
}
  1. Right-click the Client project and select 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 “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 Mar 28, 2008 at 10:32 PM by prashantbansode, version 6

Comments

No comments yet.