How to: Use the SQL Server Role Provider with Windows Authentication in WCF Calling 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 Windows authentication over the wsHttpBinding binding to authenticate your users against a Microsoft SQL Server® role provider. The article shows you how to configure the role provider, configure WCF, and test the service with a sample WCF client. Use of the SQL Server role provider requires that you first set up and use the SQL Server membership provider.

Contents

  • Objectives
  • Overview
  • Summary of Steps
  • Step 1: Create a WCF Service with Windows Authentication
  • Step 2: Create a Role Store for the SQL Server Role Provider
  • Step 3: Grant Access Permission to the WCF Service Process Identity
  • Step 4: Enable and Configure the Role Provider
  • Step 5: Create and Assign Roles to Windows Accounts
  • Step 6: Implement Declarative Role-based Security
  • Step 7: Create a Test Client
  • Step 8: Add a WCF Service Reference to the Client
  • Step 9: Test the Client and WCF Service
  • Additional Resources

Objectives

  • Learn how to configure the SQL Server role provider to use Microsoft Windows® accounts for authorizing users of the service.
  • Learn how to create a WCF service hosted in Microsoft Internet Information Services (IIS).
  • Learn how to expose the WCF service through netTcpBinding.
  • Learn how to call the service from a test client.

Overview

Windows authentication is suited for scenarios in which your users have domain credentials. In the scenario described in this how-to article, users are authenticated against their Windows domain account and authorized against roles in the SQL Server role provider. The netTcpBinding binding offers improved performance over an HTTP binding. Because IIS 6.0 cannot host a TCP binding, the scenario described in this how-to article instead hosts WCF in a Windows service. The WCF service with netTcpBinding can be consumed by a WCF-enabled .NET application through the use of a service reference. WCF transport security is used to support a secure communication channel in a point-to-point scenario. In general, you should always use transport security unless you need the additional flexibility that message security affords. For example, you would use message security for scenarios in which there are intermediaries who need to inspect and re-route the message.

You will first create a new WCF service and set the clientCredentialType attribute to Windows on netTcpBinding in order to configure the WCF service to use Windows authentication. You will then create a new Windows service and configure it to host your WCF service. Next, you will install a certificate on the server and configure it for WCF so that messages sent between the client and server are encrypted. You will create a role store, populate it with roles, and map Windows accounts to these roles. You will then configure the role store to grant access to the WCF process identity. Finally, you will use the PrincipalPermissionAttribute in your WCF service code to specify which roles are allowed to access specific operations in your WCF service.

Summary of Steps

  • Step 1: Create a WCF Service with Windows Authentication
  • Step 2: Create a Role Store for the SQL Server Role Provider
  • Step 3: Grant Access Permission to the WCF Service Process Identity
  • Step 4: Enable and Configure the Role Provider
  • Step 5: Create and Assign Roles to Windows Accounts
  • Step 6: Implement Declarative Role-based Security
  • Step 7: Create a Test Client
  • Step 8: Add a WCF Service Reference to the Client
  • Step 9: Test the Client and WCF Service

Step 1: Create a WCF Service with Windows Authentication

In this step, you create a WCF service using netTcpBinding with Windows authentication and WCF transport security.

  1. In Microsoft Visual Studio® 2008, create a sample Windows service by creating a project and selecting the Windows Service project template. Add an installer to the Windows service project so that it can be installed on the host machine.

  2. Create a sample WCF service in Visual Studio 2008 by creating a new Web site project and selecting the WCF Service project template.

  3. Modify the Windows service to host the WCF service by overriding the OnStart() and OnStop() methods to start and stop the WCF service within the Windows service.

  4. Configure the WCF service to use netTcpBinding with transport security by using the WCF Configuration Editor.

  5. Add a mexHttpBinding binding to the WCF service so that it can publish metadata.

    This interface will allow client applications to generate a proxy from the service definition.

  6. Install the Windows service by calling the installer from the command line using installutil.exe.

For more information on these steps, see “How to: Use netTcpBinding with Windows Authentication and Transport Security in WCF from Windows Forms” and follow Steps 1 through 6.

Step 2: Create a Role Store for the SQL Server Role Provider

The SQL Server role provider stores user information in a SQL Server database. You can create your SQL Server role 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 r
    

    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 r specifies to add only the role provider feature.

Step 3: 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 Microsoft 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.

  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_Roles_FullAccess database role.

You can perform these steps by using Enterprise Manager or by running 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 roles database
USE aspnetdb
GO
sp_grantdbaccess 'NT AUTHORITY\Network Service', 'Network Service'

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

Note

Notes:
If you are running on Microsoft Windows XP, add the ASPNET database user instead of Network Service because 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.

Step 4: Enable and Configure the Role Provider

In this step, you configure the use of the SQL Server role provider in your WCF service.

  1. In the web.config file, verify that you have a connection string similar to the following:

    <connectionStrings>
      <add name="MyLocalSQLServer"
           connectionString="Initial Catalog=aspnetdb;
          data source=.\sqlexpress;Integrated Security=SSPI;" />
    </connectionStrings>
    
  2. Add a <roleManager> element inside the <system.web> element as shown in the following example. Note the use of the <clear/> element, which prevents the default provider from being loaded and then never used.

    ...
    <system.web>
      <roleManager enabled="true" defaultProvider="MySqlRoleProvider" >
        <providers>
          <clear/>
          <add name="MySqlRoleProvider"
               connectionStringName="MyLocalSQLServer"
               applicationName="MyAppName"
               type="System.Web.Security.SqlRoleProvider" />
        </providers>
      </roleManager>
    </system.web>
    ...
    
  3. Save the Web.Config file; otherwise the changes might get lost during execution of the following steps.

  4. 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 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.

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

  6. Select the default behavior "ServiceBehavior".

  7. In the Behavior: ServiceBehavior section, click the Add button.

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

  9. In the Configuration section, under Service Behaviors, select serviceAuthorization.

  10. Set the principalPermissionMode attribute to UseAspNetRoles by choosing this option from the drop-down list.

  11. Set the roleProviderName attribute to “MySqlRoleProvider”, which you created above.

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

  13. In Visual Studio, verify your configuration, which should look as follows.

    …
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
           …
           <serviceAuthorization principalPermissionMode="UseAspNetRoles" 
                 roleProviderName="MySqlRoleProvider" />
           …
     </behavior>
    …
    

Step 5: Create and Assign Roles to Windows Accounts

In this step, you create roles for your application and assign users to those roles by executing SQL scripts to add them to the database directly.

  1. Create a new role, Managers, for your application.
  2. Add an existing Windows user to the Managers role.

You can perform these steps by using Enterprise Manager or by running the following script in SQL Query Analyzer.

USE aspnetdb
GO

-- Create a new role, called Managers
EXEC aspnet_Roles_CreateRole 'MyAppName', 'Managers'

-- Assign a windows user to the Managers role 
-- parameters <<Application name>>, <<User Name>>, <<Role Name>>, <<DateTime>>
EXEC aspnet_UsersInRoles_AddUsersToRoles 'MyAppName', 'Domain\userName', 'Managers', 8

Note

Important: The application name should be the same name that is specified in the role provider configuration.

Note

If you do not have Enterprise Manager or Query Analyzer, you can download Microsoft SQL Server Management Studio Express.

Step 6: Implement Declarative Role-based Security

In this step, you provide authorized access to the GetData method only for users in the Managers role.

  1. Open the Service.cs file and add a statement for using the System.Security.Permissions namespace:

    using System.Security.Permissions;
    
  2. Add the PrincipalPermissionAttribute attribute to authorize users in the Managers role with the SecurityAction as Demand to the GetData method:

    [PrincipalPermission(SecurityAction.Demand, Role="Managers")]
    public string GetData(int value)
    {
    return string.Format("You entered: {0}", value);
    }
    

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

  3. In the Name field, type Test Client and then click OK.

    A Windows Forms application is created.

Step 8: 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 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 WCFTestService and then click OK.

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

Step 9: Test the Client and WCF Service

In this step, you access the WCF service and make sure that it authorizes the users correctly.

  1. In your Client project, drag a button control onto your form.

  2. Double-click the button control to show the underlying code.

  3. In the code behind the button click, create an instance of the proxy, pass the credentials of a user with the Managers role created in step 10, 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();
    }
    
  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.

  6. Test the application by passing the credentials of a user belonging to a different role (e.g., Employee) and you should receive the security exception Access Denied. This is because the GetData operation can be accessed only by users who belong to Managers role.

Additional Resources