I realise this question has been asked and answered a lot in the last 10 years, but I need a more modern answer than most I could find.
I have an ASP.Net MVC project (C#), and have followed the MS guide to enabling Facebook and Google+ authentication. This was super simple, register the apps in the providers and uncomment three lines each in startup.auth.cs - super, super simple. It also "just works", bango I have new users created in the database that can login via these providers. Wunderbar.
Like so many applications though I need more than authentication, I also need a small amount of identity - firstname, surname, email, birthday, profile image where available.
Using a combination of Scope and Fields in the FacebookAuthenticationOptions I have managed to get the Facebook authorization screen to warn the user that the app wants their birthday, but try as I might I can't find anywhere that this information is returned in the OAuth process or any claims that might represent the half a dozen other fields I've asked for.
Many "solutions" online talked about overriding the "OnAuthenticated" delegate of the FacebookAuthenticationOptions.Provider (which is a FacebookAuthenticationProvider). I've pasted in some stolen code but it never hits the breakpoint in there.
After I get this working with Facebook, I had hoped to repeat with Google+, Twitter, and Microsoft account providers and I'm hoping it's a standardised approach where I can tell each provider what fields I want in their format, then get them all out using a standard getter somewhere. As I understand it that is actually the whole underlying point of OAuth - no?
So in my startup.auth.cs (fake Id and secret of course):
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "xxxxxxxxxxx",
AppSecret = "xxxxxxxxxxxxxxxxxxxxx",
Scope = { "user_birthday", "public_profile", "email" },
Fields = { "user_birthday", "picture", "name", "email", "gender", "first_name", "last_name" },
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async ctx =>
{
Console.WriteLine("auth"); //this breakpoint never hits
ctx.Identity.AddClaim(new Claim("FacebookAccessToken", ctx.AccessToken));
foreach (var claim in ctx.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
string claimValue = claim.Value.ToString();
if (!ctx.Identity.HasClaim(claimType, claimValue))
{
ctx.Identity.AddClaim(new Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
}
}
}
});