Facebook App Template - Extended permissions loop

Topics: ASP.NET MVC
Jan 28, 2014 at 9:43 AM
Hello

I am starting development on a Facebook app and noticed a peculiarity while using the MVC4 Facebook App template. The default login flow requests basic public profile info and friends list (as expected), upon granting that permission the user is prompted to grant the email and photos extended permissions. If granted everything works as expected. However, if the user opts to skip these extended permissions they are simply prompted to grant them again and thus the loop begins.

My understanding is that at this point the user should be redirected to the AuthorizationRedirectPath (by default Home controller > Permissions action) which should then display the permissions required and provide a button to start the request again. The advantage here is that, in accordance with the Facebook developer login recommendations, where possible, permission requests should be delayed until said permissions are about to be used.

I found the issue in FacebookAuthorizeFilter. On line 76 null is passed through (i.e. no extra permissions are being requested when constructing this login url) to request basic login permissions only. This makes sense, of course. The problem occurs on line 91 where boolean hasError is set to false as parsedQueries doesn't return any "error" query parameter. This causes the check on line 96 to skip the AuthorizationRedirectPath process and just repeat the previous request with the missing permissions.

I wonder if the Facebook process changed at some point as the current query parameters returned at the point of failure (when the user opts to skip granting the extended permissions) only contain a code and not the expected error.

Any assistance would be greatly appreciated
Developer
Feb 3, 2014 at 7:01 PM
Do you have a sample controller we can take a look at? This will help us ensure that we're looking at the same problem.
Feb 4, 2014 at 5:48 AM
Edited Feb 4, 2014 at 5:49 AM
Thank you for the attention @nowakra, I'm now certain that the problem is with Facebook. At some point they stopped returning errors for cases where the extended permissions were skipped but the app had still been authorized. The sample controller is the following added by default by the template:
[FacebookAuthorize("email", "user_photos")]
public async Task<ActionResult> Index(FacebookContext context)
{
  if (ModelState.IsValid)
  {
    var user = await context.Client.GetCurrentUserAsync<MyAppUser>();
    return View(user);
  }

  return View("Error");
}
I've considered added a session variable to indicate a redirect has occured to request extended permissions for that user. Upon posting their choice ('skip' or 'ok') I could check if they have the permissions and, if they don't and they've already been redirected to request them then simply send them to an error / explanation of permissions page.

It just seems strange that Facebook wouldn't report the result of such an important user action.
Feb 6, 2014 at 10:20 PM
Hi Mjduminy.

Thanks for reporting this issue.

I investigate this issue and do repo the problem. Your finding is right.

There is a mechanism in our Facebook authorization filter to decide whether we will redirect to
  1. App’s front page therefore to request permission if required ones are not granted, or
  2. A designated authorization error page to notify user the permission is missing, in which case no further permission request will send.
The situation you run into is that the route 1 is always triggered. The reason why we do that is because we’re expecting an “error” parameter in the call back from facebook OAuth dialog when user cancel a permission request. However, we observe that Facebook doesn’t add “error” parameter. As a result an infinite loop is constructed. The behavior is different from what is stated in the Facebook’s document (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow).

We can't simply remove the "hasError" condition, because we need to distinguish the scenario of the first time login and later login.

So questions:
1) Why does Facebook not send the right query string?
2) How can we solve the situation properly.

I'll file a bug to track this issue. And again thank you for reporting the bug.

Regards,
Troy Dai
Feb 14, 2014 at 12:00 AM
Hi,

I am having the same issue reported in this discussion. Are there any updates to the code?

Thanks

Ben
Feb 17, 2014 at 9:18 PM
Hi,

Following issue has been filed.

https://aspnetwebstack.codeplex.com/workitem/1666

Regards,
Troy