Reputation: 93
Using ASP.NET Core MVC RC2 I am trying to retrieve the Facebook user profile picture. To do this I have the following lines in the Configure method of the Startup class
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = Configuration["Authentication:Facebook:AppId"],
AppSecret = Configuration["Authentication:Facebook:AppSecret"],
Scope = { "user_birthday" },
Fields = { "birthday", "picture" },
});
In the AccountControllers ExternalLoginCallback method I was expecting to see the data for the picture in the ClaimsPrincipal collection which can be accessed via info.Principal but I cannot see any claim associated with picture.
Is this the right way to retrieve the Facebook user profile picture or am I missing something?
Upvotes: 4
Views: 4240
Reputation: 91
To get profile picture from Facebook, you need to configure Facebook options and subscribe at OnCreatingTicket event from OAuth.
services.AddAuthentication().AddFacebook("Facebook", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "ClientId";
options.ClientSecret = "ClientSecret";
options.Fields.Add("picture"); // <- Add field picture
options.Events = new OAuthEvents
{
OnCreatingTicket = context =>
{
var identity = (ClaimsIdentity)context.Principal.Identity;
var profileImg = context.User["picture"]["data"].Value<string>("url");
identity.AddClaim(new Claim(JwtClaimTypes.Picture, profileImg));
return Task.CompletedTask;
}
};
});
Upvotes: 1
Reputation: 14850
For anyone using Microsoft' OWIN Facebook Authentication extensions. You can extend the default FacebookAuthenticationProvider
to obtain any requested (and granted) claims to the current identity. Then register that customer provider in the middleware. A simple custom provider would look like this...
public class CustomFacebookOAuthProvider: FacebookAuthenticationProvider
{
public override Task Authenticated(FacebookAuthenticatedContext context)
{
if (context.User.IsNotNull() && context.Id.IsNotNullOrEmpty())
{
//ADD THE CLAIMS YOU WANT YOUR APP TO CONSUME
context.Identity.AddClaim(new Claim(Constants.ClaimsTypes.PhotoUrl
, "https://graph.facebook.com/{0}/picture?height={1}&width={1}".With(context.Id, Constants.UI.DEFAUL_PROFILE_PICTURE_DIMENS)));
}
return base.Authenticated(context);
}
}
The implementation is simple, we only need to override the Authenticated
method, which will be called once the OAuth provider (Facebook in this example) has authenticated the user and returned the user details (translate this to a call to the UserInfo endpoint).
The context.User
is a NewtonSoft.Json.JObject
which can be desrialized into your own class...
var user = context.User.ToObject<FacebookOAuthUser>();
Just make sure you create the FacebookOAuthUser
class with the required properties.
Once you have that provider in place, all you need to do register it...
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
Caption = "Sign-in with Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ApplicationSettings.FacebookAppID,
AppSecret = ApplicationSettings.FacebookAppSecret,
Provider = new CustomFacebookOAuthProvider()
});
Upvotes: 2
Reputation: 49789
Using 3rd Party Authentication, you are only get information about who user is (user authentication).
Using Facebook Authentication, after successful login you receive an access token to Facebook API and a collection of user data (claims) only from UserInformationEndpoint (https://graph.facebook.com/v2.6/me).
After that, you should call Facebook API methods if you want to get any other user specific information (like user picture in your case - Facebook Graph API. User Picture).
If you are interesting about claims that ASP.Core implementation of Facebook login is filled, looks into CreateTicketAsync
method in FacebookHandler class - here the collection of claims is created.
Upvotes: 2