1

This code was working fine for a year or so, this problem is related to facebook changing their API response to JSON (instead of regular query string)

It's a MVC5 project, I updated to https://www.nuget.org/packages/Microsoft.Owin.Security.Facebook/3.1.0-rc1 as suggested here: ASP.NET MVC5 OWIN Facebook authentication suddenly not working and also try to simplify my call as suggested here: https://github.com/aspnet/AspNetKatana/issues/38

In addition I tried adding the BackchannelHttpHandler class (but removed it as it was not working for me), Also, I deleted my facebook web app (it was API 2.4) and created a new one (2.8) that is not approved yet, but I think test app should be working regardless.

I keep getting 302 error=access_denied

This is the code I'm using:

var facebookAuthOptions = new FacebookAuthenticationOptions();
facebookAuthOptions.AppId = "xxx";
facebookAuthOptions.AppSecret = "yyy";
facebookAuthOptions.SendAppSecretProof = true;
facebookAuthOptions.CallbackPath = new PathString("/signin-facebook");

facebookAuthOptions.Scope.Add("public_profile");
facebookAuthOptions.Scope.Add("email");
facebookAuthOptions.Scope.Add("user_birthday");

// added for Microsoft.Owin.Security.Facebook/3.1.0-rc1
facebookAuthOptions.Fields.Add("email");
facebookAuthOptions.Fields.Add("birthday");
facebookAuthOptions.Fields.Add("gender");
facebookAuthOptions.Fields.Add("locale");
facebookAuthOptions.Fields.Add("location");
facebookAuthOptions.Fields.Add("timezone");

facebookAuthOptions.Provider = new FacebookAuthenticationProvider()
{
    OnAuthenticated = (context) =>
    {
        context.Identity.AddClaim(new Claim("FacebookAccessToken", context.AccessToken));

        var expiryDuration = context.ExpiresIn ?? new TimeSpan();
        context.Identity.AddClaim(new Claim("urn:facebook:expires_in", DateTime.UtcNow.Add(expiryDuration).ToString(CultureInfo.InvariantCulture)));

    // Add all other available claims
    foreach (var claim in context.User)
    {
        var claimType = string.Format("urn:facebook:{0}", claim.Key);
        var claimValue = claim.Value.ToString();
        if (!context.Identity.HasClaim(claimType, claimValue))
            context.Identity.AddClaim(new Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
    }

    return Task.FromResult(0);
}
};
app.UseFacebookAuthentication(facebookAuthOptions);

The net traffic looks like this:

https://localhost:44300/external-providers (302)

https://www.facebook.com/v2.8/dialog/oauth?response_type=code&client_id=1897713540512505&redirect_uri=https%3A%2F%2Flocalhost%3A44300%2Fsignin-facebook&scope=&state=OXOiCtOJPEK5WCQkEJt-mH3lxEnTCXG3YcGFtW7j_dyuPd_9LevphavHobpB6EH3Wfb8BpbhqST13SacFMB3OnddsgnslzcAX7KnMpzpnEcfFI3KErmByenV9xn1IEt7PhY4TjXi5KHFNUp1PVu_ikUBnvf0hJpY2IK0fczvQLVmGKplJV-g6qsEMYXfKHNYoqjDiu9cA-iGIPXfRxPxZg (302)

https://localhost:44300/signin-facebook?code=AQDrGJ9sqk0ENVw_7RW3zmauzV1Gf6rWXBotgAKf6uBbdryamL5RMHiOgIrBiPYdy8CA9HC9hq2sahu2bt-VwznOJ8PNFTxRmLCe0PRrwxSsffscHSdNzjz16jjavuupse087mB_2KhZeKKWeS2Rlwabcfa-n4FGIcyDizpOKTWJl_J6PFAjWv3XfPy1zkbLz0cAsTdQ8t8pOARPhP5nKwUIGN5GuS4fzuGhgPCerlPyHknK0BWcFrRC0fa_n3X2d0-zANu6nzhRspssDTWmIAr9PZCLOlpSMlJeb1NrebECNbw4YqGzScCWxBRVL8YAfQ4&state=OXOiCtOJPEK5WCQkEJt-mH3lxEnTCXG3YcGFtW7j_dyuPd_9LevphavHobpB6EH3Wfb8BpbhqST13SacFMB3OnddsgnslzcAX7KnMpzpnEcfFI3KErmByenV9xn1IEt7PhY4TjXi5KHFNUp1PVu_ikUBnvf0hJpY2IK0fczvQLVmGKplJV-g6qsEMYXfKHNYoqjDiu9cA-iGIPXfRxPxZg (302)

https://localhost:44300/signup-connect?error=access_denied (302)

https://localhost:44300/signout (200)

Community
  • 1
  • 1
Yovav
  • 2,557
  • 2
  • 32
  • 53

1 Answers1

1

Ok, I finally found the problem, this cost me 3 days, definitely the most annoying bug of 2017.

So, the new Owin RC1 update is working. also, in my case, no need to specify anything in facebookAuthOptions.Fields nor changing anything else with the provider etc. (see https://github.com/aspnet/AspNetKatana/issues/38)

The problem I had (and still do) is that the facebook page SETTING : Advanced : Require App Secret - was always set to YES, now, as part of the mass confusion after Facebook changed their APIs, I also deleted my facebook app and created a new one using the latest 2.8 APIs.

I also have this in my code: facebookAuthOptions.SendAppSecretProof = true; So that should have been working, but for now I set Require App Secret to NO.

I'm thinking facebook did something on their end to the Require App Secret option and broke it, OR maybe the new Owin RC1 update does not pass SendAppSecretProof = true in the FacebookAuthenticationOptions

Anyway, that was a tough one, hope someone finds this before spending whole 3-4 days on it.

This is the current facebook settings that works:

PRODUCTS: Facebook Login:

Client OAuth Login: NO

Web OAuth Login: YES

Embedded Browser OAuth Login: NO

Force Web OAuth Reauthentication: NO

Login from Devices: NO

Valid OAuth redirect URIs: https://localhost:44300/signin-facebook

Deauthorize Callback URL: https://localhost:44300/signout

SETTINGS: Advanced:

Require App Secret: NO

Allow API Access to App Settings: YES

Require 2-Factor Reauthorization: NO

UPDATE: the appsecret_proof was not passed correctly to the query string, this will be fixed in the new Owin version very soon, the Require App Secret can be set back to YES.

Yovav
  • 2,557
  • 2
  • 32
  • 53