AspNetKatana: [Announcement] Facebook 3.0.1 and lower no longer work

Facebook as deprecated their old OAuth endpoints that were used by Katana 3.0.1 and lower. Here’s a Fiddler trace of a failing auth flow:

#	Result	Protocol	Host	URL	Body	Caching	Content-Type	Process	Comments	Custom	
1191	302	HTTPS	localhost:44318	/Account/ExternalLogin	0	private		chrome:16236			
1202	302	HTTPS	www.facebook.com	/dialog/oauth?response_type=code&client_id=569522623154478&redirect_uri=https%3A%2F%2Flocalhost%3A44318%2Fsignin-facebook&scope=&state=gQ2fRAt8BI46eC52Z_YdSFMCYbBleCGJO5Jl1BO4yQQFl0dVjx-Z0EqMS6QGNfIHD6n7fApnqdodg6ea4E7Ky9rsnExnoW22a7mV7uYAnj089d3yKm6TN4F2YoFgeVPZPakdddB_D-b8988omDTjeQPHrfSVNFqqATAsvab15PHkSaCuk5OqWZRJUnkKtfanM2uA9E8PH4_JrNrLc4DZyd0tRfGr0C3aHUkPJMUiEq0	0	private, no-cache, no-store, must-revalidate; Expires: Sat, 01 Jan 2000 00:00:00 GMT	text/html	chrome:16236			
1203	302	HTTPS	localhost:44318	/signin-facebook?code=AQDQ5k6PZ623JZqcDBHkeK6-uryTkyuKZWGD5Hk_rcLV2sYArbQKJE-d-WIvHGikif_5VtclZojZUInsOmV_KEYUYD9jL3Gn0qKKzdk6574_Ya8IoAVPpvm9hsHZ50bKAxItn01fTW54hhGRxUFpX4yCLqXrLtVgImctDxM73XGTEq7poHN7nglEcU0TjFKImpc4Pu-FkkrQXoDGrD4Xeig4NCJHzvJcw8Oc8iJIBCJDSESi6Y2U5Y2Gsy4WntIkRnhCPqh3p--h_2LFqbRcjpx9KYrvPqhW9sr5eShwY1JJ8fVlKzBQmmQbgf0IvTcbckLnxJOPCsIyIFCs5xNf9AH4&state=gQ2fRAt8BI46eC52Z_YdSFMCYbBleCGJO5Jl1BO4yQQFl0dVjx-Z0EqMS6QGNfIHD6n7fApnqdodg6ea4E7Ky9rsnExnoW22a7mV7uYAnj089d3yKm6TN4F2YoFgeVPZPakdddB_D-b8988omDTjeQPHrfSVNFqqATAsvab15PHkSaCuk5OqWZRJUnkKtfanM2uA9E8PH4_JrNrLc4DZyd0tRfGr0C3aHUkPJMUiEq0	0			chrome:16236			
1205	200	HTTPS	graph.facebook.com	/oauth/access_token?grant_type=authorization_code&code=AQDQ5k6PZ623JZqcDBHkeK6-uryTkyuKZWGD5Hk_rcLV2sYArbQKJE-d-WIvHGikif_5VtclZojZUInsOmV_KEYUYD9jL3Gn0qKKzdk6574_Ya8IoAVPpvm9hsHZ50bKAxItn01fTW54hhGRxUFpX4yCLqXrLtVgImctDxM73XGTEq7poHN7nglEcU0TjFKImpc4Pu-FkkrQXoDGrD4Xeig4NCJHzvJcw8Oc8iJIBCJDSESi6Y2U5Y2Gsy4WntIkRnhCPqh3p--h_2LFqbRcjpx9KYrvPqhW9sr5eShwY1JJ8fVlKzBQmmQbgf0IvTcbckLnxJOPCsIyIFCs5xNf9AH4&redirect_uri=https%3A%2F%2Flocalhost%3A44318%2Fsignin-facebook&client_id=xxxxx&client_secret=xxxxxxxx	251	private, no-cache, no-store, must-revalidate; Expires: Sat, 01 Jan 2000 00:00:00 GMT	application/json; charset=UTF-8	iisexpress:1144			
1206	302	HTTPS	localhost:44318	/Account/ExternalLoginCallback?error=access_denied	442	private	text/html; charset=utf-8	chrome:16236			
1207	200	HTTPS	localhost:44318	/Account/Login	2,134	private	text/html; charset=utf-8	chrome:16236			

Note the /Account/ExternalLoginCallback?error=access_denied request.

If you enable logging here’s the message (caused by a change in Facebook’s response format): https://github.com/aspnet/AspNetKatana/wiki/Debugging#logging

Microsoft.Owin.Security.Facebook.FacebookAuthenticationMiddleware Error: 0 : Authentication failed
System.ArgumentNullException: Value cannot be null.
Parameter name: stringToEscape
   at System.Uri.EscapeDataString(String stringToEscape)
   at Microsoft.Owin.Security.Facebook.FacebookAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
    ProcessId=1144
    DateTime=2017-03-27T20:53:38.6034000Z

This has been fixed in Katana 3.1.0-RC1 which is now available on nuget.org.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 16
  • Comments: 78 (26 by maintainers)

Most upvoted comments

Okay folks, here is a configuration that works for me. The authentication itself works with minimal configuration. To retrieve specific fields, I still needed to use the FacebookAuthenticationProvider - otherwise the claims were not added and named properly.

var facebookOptions = new FacebookAuthenticationOptions()
{
	AppId = "xxxxx",
	AppSecret = "xxxxx",
};

// Set requested scope
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("public_profile");

// Set requested fields
facebookOptions.Fields.Add("email");
facebookOptions.Fields.Add("first_name");
facebookOptions.Fields.Add("last_name");

facebookOptions.Provider = new FacebookAuthenticationProvider()
{
	OnAuthenticated = (context) =>
	{
		// Attach the access token if you need it later on for calls on behalf of the user
		context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));

		foreach (var claim in context.User)
		{
			//var claimType = string.Format("urn:facebook:{0}", claim.Key);
			var claimType = string.Format("{0}", claim.Key);
			string claimValue = claim.Value.ToString();

			if (!context.Identity.HasClaim(claimType, claimValue))
				context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
		}

		return Task.FromResult(0);
	}
};

app.UseFacebookAuthentication(facebookOptions);

With this configuration you can get and read from the user info like this:

var info = await AuthenticationManager.GetExternalLoginInfoAsync();

if (info != null)
{
	var firstName = info.ExternalIdentity.Claims.First(c => c.Type == "first_name").Value;
	var lastName = info.ExternalIdentity.Claims.First(c => c.Type == "last_name").Value;
}

@Andrei, you can get the updated version at https://www.nuget.org/packages/Microsoft.Owin.Security.Facebook/3.1.0-rc1, or go to Tools > nuget package manager > manage packets for solution, click on “updates” and check “include prerelease”.

Cheers

@Tratcher in the callback action method (ExternalLoginCallback) var loginInfo = await OwinContext.Authentication.GetExternalLoginInfoAsync();

loginInfo is always null if I haven’t included the following properties:

BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name"

Yes, 3.1.0 will be released any day now. Just finishing the verification.

@YovavGad it’s a NuGet package feed with the fixes. You can browse the feed here: https://dotnet.myget.org/gallery/katana-dev

And click on “Connect to feed” to see how to use the feed from your NuGet.config.

@embee8 Fields can be specified on Options now, just like Scope.