During a recent consulting, I helped a client to resolve his authentication issues with his existing Web application and Windows Phone application.

image

Using the existing MembershipProvider
If you have already an existing Web application and you want to extend it throughout a Windows Phone application you can use the existing System.Web.ApplicationServices for the authentication.

You can do this by creating a new WCF service file and expose the built-in AuthenticationService.

<%@ ServiceHost Language="C#"
                Service="System.Web.ApplicationServices.AuthenticationService" %>

In the web.config of the Asp.net Web application you have to add following sections:

  <system.web.extensions>
    <scripting>
      <webServices>
        <authenticationService enabled="true" requireSSL="false"/>
      </webServices>
    </scripting>
  </system.web.extensions>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name=" ">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior name="AuthenticationServiceBehaviors">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
                               multipleSiteBindingsEnabled="true" />
    <services>
      <service name="System.Web.ApplicationServices.AuthenticationService" 
               behaviorConfiguration="AuthenticationServiceBehaviors">
        <endpoint contract="System.Web.ApplicationServices.AuthenticationService"
            binding="basicHttpBinding" />
      </service>
    </services>
  </system.serviceModel>

You also need to configure the WCF service itself by using the AspNetCompatibilityRequirements attribute.

[ServiceContract(Namespace = "LieberLieber.Mobile")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(
              RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CompanyService

After you have added a service reference to the AuthenticationService.svc and CompanyService.svc you have to enable cookies for the Windows Phone application.

Add following attribute enableHttpCockieContainer and set the value to true.

   <bindings>
       <basicHttpBinding>
           <binding enableHttpCookieContainer="true" name="BasicHttpBinding_AuthenticationService" maxBufferSize="2147483647
               maxReceivedMessageSize="2147483647">
               <security mode="None" />
           </binding>
           <binding enableHttpCookieContainer="true" name="BasicHttpBinding_CompanyService" maxBufferSize="2147483647"
               maxReceivedMessageSize="2147483647">
               <security mode="None" />
           </binding>
       </basicHttpBinding>
   </bindings>

One important notice:

If you need to update the service reference you will get following Microsoft Visual Studio error: “The configuration for the service reference could not be updated due to the following issue: Unrecognized attribute ‘enableHttpCockieContainer’.

image

To resolve this issue just remove the attribute. Update the service reference and add the attribute again.

Within the Windows Phone application you can now use the AuthenticationService’s method LoginAsync.

    readonly CookieContainer _coockieContainer = new CookieContainer();
    private void Authenticate(string userName,string password)
    {
      var authService = new AuthenticationService.AuthenticationServiceClient();
      authService.CookieContainer = _coockieContainer;
      authService.LoginCompleted += authService_LoginCompleted;
      authService.LoginAsync(userName,password,"",true);
    }

If you make now a method service call, you have to set the same CookieContainer.

    private void GetCompanyName()
    {
      var client = new CompanyServiceClient();
      client.CookieContainer = _coockieContainer;
      client.GetCompanyNameCompleted += client_GetCompanyNameCompleted;
      client.GetCompanyNameAsync();
    }

Authentication without MembershipProvider

If you are using your own authentication method you have to set the authentication cookie by yourself.

   public bool Authenticate(string userName, string password)
   {
     if (userName == "lieberlieber" && password == "ll%123")
     {
      System.Web.Security.FormsAuthentication.SetAuthCookie(userName, false);
      return true;
     }
     return false;
    }

One important thing to remember

If you are using Basic Authentication the username and password are sent in plaintext. That means you should definitely use SSL.

Here you can find a running solution.