Use ASP.NET Membership and Role Providers in Windows Communication Foundation

It's possible to use ASP.NET membership and role providers for authentication and authorization in Windows Communication Foundation.

To enable ASP.NET membership for authentication you need to modify service configuration file and add appropriate items for ASP.NET membership to it then set Windows Communication Foundation configurations to use it.

For example here I add connection string for my SQL Server database to use its membership data for authentication:

<connectionStrings>

  <remove name="MyConnection" />

  <add name="MyConnection"

      connectionString="Data Source=KEYVAN-XP;Initial Catalog=HelloMembership;Integrated Security=True"

      providerName="System.Data.SqlClient" />

</connectionStrings>

Now I add my membership configurations to service configuration file:

<system.web>

  <membership defaultProvider="SqlMembershipProvider">

    <providers>

      <clear />

      <add

        name="SqlMembershipProvider"

        type="System.Web.Security.SqlMembershipProvider"

        connectionStringName="MyConnection"

        applicationName="/HelloService"

        enablePasswordRetrieval="false"

        enablePasswordReset="false"

        requiresQuestionAndAnswer="false"

        requiresUniqueEmail="true"

        passwordFormat="Hashed" />

    </providers>

  </membership>

 

  <compilation debug="true"/>

</system.web>

Then I use wsHttpBinding and set its mode to Message then apply UserName credential type for it to apply UserName authentication:

<bindings>

  <wsHttpBinding>

    <binding name="MyBinding">

      <security mode="Message">

        <message clientCredentialType="UserName"/>

      </security>

    </binding>

  </wsHttpBinding>

</bindings>

And finally I set my UserName authentication to use ASP.NET membership by adding a <userNameAuthentication /> element to my service behavior.  First it's necessary to set userNamePasswordValidationMode attribute to MembershipProvider then use ASP.NET membership whose configurations are used before to set membershipProviderName attribute.

<behaviors>

  <serviceBehaviors>

    <behavior name="MyBehavior">

      <serviceMetadata httpGetEnabled="true" />

      <serviceCredentials>

        <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"

                                membershipProviderName="SqlMembershipProvider"/>

      </serviceCredentials>

    </behavior>

  </serviceBehaviors>

</behaviors>

So after these changes my service configuration file looks like this:

<?xml version="1.0"?>

<configuration>

  <connectionStrings>

    <remove name="MyConnection" />

    <add name="MyConnection"

        connectionString="Data Source=KEYVAN-XP;Initial Catalog=HelloMembership;Integrated Security=True"

        providerName="System.Data.SqlClient" />

  </connectionStrings>

 

  <system.serviceModel>

    <services>

      <service name="MyService.Hello" behaviorConfiguration="MyBehavior">

        <endpoint contract="MyService.IHello" binding="wsHttpBinding"

                  bindingConfiguration="MyBinding" />

      </service>

    </services>

 

    <bindings>

      <wsHttpBinding>

        <binding name="MyBinding">

          <security mode="Message">

            <message clientCredentialType="UserName"/>

          </security>

        </binding>

      </wsHttpBinding>

    </bindings>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="MyBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceCredentials>

            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"

                                    membershipProviderName="SqlMembershipProvider"/>

          </serviceCredentials>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

 

  <system.web>

    <membership defaultProvider="SqlMembershipProvider">

      <providers>

        <clear />

        <add

          name="SqlMembershipProvider"

          type="System.Web.Security.SqlMembershipProvider"

          connectionStringName="MyConnection"

          applicationName="/HelloService"

          enablePasswordRetrieval="false"

          enablePasswordReset="false"

          requiresQuestionAndAnswer="false"

          requiresUniqueEmail="true"

          passwordFormat="Hashed" />

      </providers>

    </membership>

 

    <compilation debug="true"/>

  </system.web>

</configuration>

Now I can use UserName authentication on client side to access to my service methods by passing ASP.NET membership credentials to client proxy.

Second usage of ASP.NET providers in Windows Communication Foundation is for authorization.

To implement this for my example, I add ASP.NET configuration for role provider:

<roleManager enabled ="true" defaultProvider ="SqlRoleProvider" >

  <providers>

    <add name ="SqlRoleProvider"

      type="System.Web.Security.SqlRoleProvider"

      applicationName="/HelloService"

      connectionStringName="MyConnection" />

  </providers>

</roleManager>

At this point I use <serviceAuthorization /> element under <behavior /> element to configure authorization for my Windows Communication Foundation service.  By setting principalPermissionMode attribute to UseAspNetRoles and roleProviderName attribute to appropriate role provider name I can enable ASP.NET role provider authorization for my Windows Communication Foundation service.

<behaviors>

  <serviceBehaviors>

    <behavior name="MyBehavior">

      <serviceMetadata httpGetEnabled="true" />

      <serviceCredentials>

        <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"

                                membershipProviderName="SqlMembershipProvider"/>

      </serviceCredentials>

      <serviceAuthorization principalPermissionMode="UseAspNetRoles"

                            roleProviderName="SqlRoleProvider">

      </serviceAuthorization>

    </behavior>

  </serviceBehaviors>

</behaviors>

At the end my Web.Config is this:

<?xml version="1.0"?>

<configuration>

  <connectionStrings>

    <remove name="MyConnection" />

    <add name="MyConnection"

        connectionString="Data Source=KEYVAN-XP;Initial Catalog=HelloMembership;Integrated Security=True"

        providerName="System.Data.SqlClient" />

  </connectionStrings>

 

  <system.serviceModel>

    <services>

      <service name="MyService.Hello" behaviorConfiguration="MyBehavior">

        <endpoint contract="MyService.IHello" binding="wsHttpBinding"

                  bindingConfiguration="MyBinding" />

      </service>

    </services>

 

    <bindings>

      <wsHttpBinding>

        <binding name="MyBinding">

          <security mode="Message">

            <message clientCredentialType="UserName"/>

          </security>

        </binding>

      </wsHttpBinding>

    </bindings>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="MyBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceCredentials>

            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"

                                    membershipProviderName="SqlMembershipProvider"/>

          </serviceCredentials>

          <serviceAuthorization principalPermissionMode="UseAspNetRoles"

                                roleProviderName="SqlRoleProvider">

          </serviceAuthorization>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

 

  <system.web>

    <membership defaultProvider="SqlMembershipProvider">

      <providers>

        <clear />

        <add

          name="SqlMembershipProvider"

          type="System.Web.Security.SqlMembershipProvider"

          connectionStringName="MyConnection"

          applicationName="/HelloService"

          enablePasswordRetrieval="false"

          enablePasswordReset="false"

          requiresQuestionAndAnswer="false"

          requiresUniqueEmail="true"

          passwordFormat="Hashed" />

      </providers>

    </membership>

 

    <roleManager enabled ="true" defaultProvider ="SqlRoleProvider" >

      <providers>

        <add name ="SqlRoleProvider"

          type="System.Web.Security.SqlRoleProvider"

          applicationName="/HelloService"

          connectionStringName="MyConnection" />

      </providers>

    </roleManager>

 

    <compilation debug="true"/>

  </system.web>

</configuration>

Now playing: Eric Clapton - Revolution

[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.

5 Comments : 12.13.06

Feedbacks

 avatar
#1
DotNetKicks.com
12.13.2006 @ 12:17 PM
You've been kicked (a good thing) - Trackback from DotNetKicks.com
 avatar
#2
Sandro
09.04.2007 @ 6:01 AM
I follow your guidelines but I receive from the service: The service certificate is not provided. Specify a service certificate in ServiceCredentials. Thanks
 avatar
#3
Ron
11.01.2007 @ 8:34 AM
This is only a partial sample. Can you please add to this the client-side of things? Let's see what the clients config file looks like as well as the code necessary on the client to pass user ID and password. Also, how about showing us how to do this same thing using a TCP endpoint instead of HTTP.
 avatar
#4
Johnson
03.05.2008 @ 12:15 AM

How to use Kerberos with WCF with ASP.NET Membership and Role Providers?

 avatar
#5
Karen
05.07.2008 @ 9:51 AM

Can I keep WCF service separately from Web and has autontication, profile and role access in WCF from web site's web config. I have written site with ASP.NET autontication, profile and role providers. Now I have added SilverLight which has to have access to loged in user's profile. I use WCF to get access to profile. But nothing happen because WCF and Web different projects and have different Web.config files. What can I do ?

Leave a Comment