There appears to be a lot of documentation on how to get additional information from a Facebook profile using ASP.NET Identity and an MVC client, but I can't seem to find anything on how to access the additional info claims from a Web API controller.
My Startup.Auth.cs ConfigAuth method contains this, which seems to work alright if I breakpoint on JObject wholeUser = context.User
String XmlSchemaString = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims";
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
AppId = "*",
AppSecret = "*",
Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
JObject wholeUser = context.User;
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:email", context.Email, XmlSchemaString, "Facebook"));
return Task.FromResult(0);
}
}
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
Once authenticated, wholeUser will have all the information I need like birthdate, etc. but once out of this scope, I don't know how to get to it.
I need to get this information in AccountController.RegisterExternal, but I can't seem to configure it correctly. A lot of the MVC doco around uses this in the ExternalLoginCallback method:
ClaimsIdentity claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
But AuthenticationManager can't be found in Web API, so if I change it to just Authentication, it returns null unless I change the parameter to be DefaultAuthenticationTypes.ExternalBearer. This is as close as I get, but the returned ClaimsIdentity object doesn't have any of the additional claims - just the username and ID.
So overall, it's as though I'm getting the information from Facebook properly and cramming into context.Identity, but then I have no idea how to access it from the controller. NB: the context object in ConfigAuth is of type Microsoft.Owin.Security.Facebook.FacebookAuthenticatedContext
I'm not sure if you need the same thing that I did, but take a look at http://aliu.ro/easy-mvc4-facebook-authentication-example/
There is a small sample project that does the Facebook Auth, retrieves the access token and makes a call using some .NET SDK that I found in NuGet
I have used the following code here;
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
AppId = "*",
AppSecret = "**",
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
},
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
Now in the RegisterExternal method, the claim is available to me. I just can't figure out how to persist it in the Identity so that it can be used in other Controller calls. If i add the claim to the identity then it seems to break the User.Identity object on other calls;
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
And the FromIdentity method;
public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
{
if (identity == null)
{
return null;
}
string userEmail = string.Empty;
string userFacebookAccessToken = string.Empty;
Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
Claim facebookToken = identity.Claims.First(x => x.Type.Contains("access_token"));
Claim emailDetails = identity.FindFirst(ClaimTypes.Email);
if (facebookToken != null) userFacebookAccessToken = facebookToken.Value;
if (emailDetails != null) userEmail = emailDetails.Value;
//string userEmail = identity.Claims.First(x => x.Type.Contains("emailaddress")).Value;
if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
|| String.IsNullOrEmpty(providerKeyClaim.Value))
{
return null;
}
if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
{
return null;
}
return new ExternalLoginData
{
LoginProvider = providerKeyClaim.Issuer,
ProviderKey = providerKeyClaim.Value,
UserName = identity.FindFirstValue(ClaimTypes.Name),
Email = userEmail,
FacebookAccessToken = userFacebookAccessToken
};
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.