Question

I'm following the post at http://ntotten.com/2013/03/14/using-windows-azure-mobile-services-with-the-facebook-sdk-for-windows-phone/ and I can successfully get a Facebook access token. However when I submit the access token as a JObject to the MobileServiceClient.LoginAsync(provider, token) method I get an IvalidOperationException (Unauthorized). The Code, Request and Response (from the exception) are below...

Code

private async Task Authenticate()
{
    while (user == null)
    {
        try
        {
            fbSession = await App.FacebookSessionClient.LoginAsync("email,publish_stream,friends_about_me");
            var client = new FacebookClient(fbSession.AccessToken);
            var token = JObject.FromObject(new
            {
                access_token = fbSession.AccessToken
            });
            user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token); // this line causes the exception
        }
        catch (InvalidOperationException e)
        {
        }
    }
}

Request

{Method: POST, RequestUri: 'https://[MY-DOMAIN].azure-mobile.net/login/facebook', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
  X-ZUMO-INSTALLATION-ID: f13ec5fb-XXXX-XXXX-XXXX-f249415499de
  X-ZUMO-APPLICATION: jUjMFbasVpKwbktxTWcBShXXXXXXXXXX
  Accept: application/json
  User-Agent: ZUMO/1.0
  User-Agent: (lang=Managed; os=Windows Phone; os_version=8.10.0.12359; arch=Win32NT; version=1.0.20402.0)
  X-ZUMO-VERSION: ZUMO/1.0 (lang=Managed; os=Windows Phone; os_version=8.10.0.12359; arch=Win32NT; version=1.0.20402.0)
  Content-Type: application/json; charset=utf-8
  Content-Length: 223
}}

Response

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 0.0, Content: System.Net.Http.StreamContent, Headers:
{
  Server: Microsoft-IIS/8.0
  WWW-Authenticate: Basic realm="Service"
  X-Powered-By: ASP.NET
  Set-Cookie: ARRAffinity=e1254f762d2198b2b306557ef6b226a2d9f70aac5e3cc654c3381bXXXXXXXXXX;Path=/;Domain=[MY-DOMAIN].azure-mobile.net
  Date: Sun, 20 Apr 2014 17:37:00 GMT
  Content-Length: 0
}}

If I remove the Facebook client access and leverage the MobileServiceClient.LoginAsync(provider) method instead, the Facebook authentication is successful but I want to have access to the Client SDK on the phone so I'm sure I've missed something. Unfortunately all my debugging and searching has left me stumped.

Was it helpful?

Solution

Based on the WWW-Authenticate header in the response I'm assuming you're using the .NET backend for the mobile service. Login with the token from access providers (Facebook / Microsoft) is still not supported in the .NET backend. If you use a mobile service with the node.js backend, then you should be able to use that code on the client-side to login to the mobile service.

Support for client-side login for those providers should come in the near future for the mobile services .NET backend.

OTHER TIPS

To solve my issue I added a User table to my DB, including a column called FacebookToken. I can then capture the Facebook access token from the Claim when a new user is being added to the table (or from any other operation on the Controller).

My PostUser method now looks like the following;

public async Task<IHttpActionResult> PostUser(User item)
{
    //get current user and facebook token...
    var currentUser = User as ServiceUser;
    Claim fbClaim = currentUser.Claims.First(c => c.Type == "urn:microsoft:credentials");
    JToken accessToken = JToken.Parse(fbClaim.Value);

    //set the facebook token on the User object...
    item.FacebookToken = accessToken["accessToken"].Value<string>();

    //insert the user record...
    User current = await InsertAsync(item);
    return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top