From e737f3207e8ceb80f6bcf1286b4ea0fec9ea72ea Mon Sep 17 00:00:00 2001 From: Mike Surcouf Date: Tue, 26 Jan 2016 13:38:50 +0000 Subject: [PATCH] Remove username from Facebook Add default fields for Facebook Remove default fields except name and email Add all the core fields for Facebook Fix location and field uniqueness --- .../FacebookHandler.cs | 70 +++++++-- .../FacebookHelper.cs | 148 ++++++++++++++++-- .../FacebookMiddleware.cs | 1 + .../FacebookOptions.cs | 7 +- 4 files changed, 202 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs index 126f48d66d..675ae51494 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs @@ -48,10 +48,22 @@ namespace Microsoft.AspNetCore.Authentication.Facebook identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } - var userName = FacebookHelper.GetUserName(payload); - if (!string.IsNullOrEmpty(userName)) + var ageRangeMin = FacebookHelper.GetAgeRangeMin(payload); + if (!string.IsNullOrEmpty(ageRangeMin)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, Options.ClaimsIssuer)); + identity.AddClaim(new Claim("urn:facebook:age_range_min", ageRangeMin, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var ageRangeMax = FacebookHelper.GetAgeRangeMax(payload); + if (!string.IsNullOrEmpty(ageRangeMax)) + { + identity.AddClaim(new Claim("urn:facebook:age_range_max", ageRangeMax, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var birthday = FacebookHelper.GetBirthday(payload); + if (!string.IsNullOrEmpty(birthday)) + { + identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday, ClaimValueTypes.String, Options.ClaimsIssuer)); } var email = FacebookHelper.GetEmail(payload); @@ -60,16 +72,22 @@ namespace Microsoft.AspNetCore.Authentication.Facebook identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } - var name = FacebookHelper.GetName(payload); - if (!string.IsNullOrEmpty(name)) + var firstName = FacebookHelper.GetFirstName(payload); + if (!string.IsNullOrEmpty(firstName)) { - identity.AddClaim(new Claim("urn:facebook:name", name, ClaimValueTypes.String, Options.ClaimsIssuer)); + identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName, ClaimValueTypes.String, Options.ClaimsIssuer)); + } - // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. - if (string.IsNullOrEmpty(userName)) - { - identity.AddClaim(new Claim(identity.NameClaimType, name, ClaimValueTypes.String, Options.ClaimsIssuer)); - } + var gender = FacebookHelper.GetGender(payload); + if (!string.IsNullOrEmpty(gender)) + { + identity.AddClaim(new Claim(ClaimTypes.Gender, gender, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var lastName = FacebookHelper.GetLastName(payload); + if (!string.IsNullOrEmpty(lastName)) + { + identity.AddClaim(new Claim(ClaimTypes.Surname, lastName, ClaimValueTypes.String, Options.ClaimsIssuer)); } var link = FacebookHelper.GetLink(payload); @@ -78,6 +96,36 @@ namespace Microsoft.AspNetCore.Authentication.Facebook identity.AddClaim(new Claim("urn:facebook:link", link, ClaimValueTypes.String, Options.ClaimsIssuer)); } + var location = FacebookHelper.GetLocation(payload); + if (!string.IsNullOrEmpty(location)) + { + identity.AddClaim(new Claim("urn:facebook:location", location, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var locale = FacebookHelper.GetLocale(payload); + if (!string.IsNullOrEmpty(locale)) + { + identity.AddClaim(new Claim(ClaimTypes.Locality, locale, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var middleName = FacebookHelper.GetMiddleName(payload); + if (!string.IsNullOrEmpty(middleName)) + { + identity.AddClaim(new Claim("urn:facebook:middle_name", middleName, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var name = FacebookHelper.GetName(payload); + if (!string.IsNullOrEmpty(name)) + { + identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + + var timeZone = FacebookHelper.GetTimeZone(payload); + if (!string.IsNullOrEmpty(timeZone)) + { + identity.AddClaim(new Claim("urn:facebook:timezone", timeZone, ClaimValueTypes.String, Options.ClaimsIssuer)); + } + await Options.Events.CreatingTicket(context); return context.Ticket; diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHelper.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHelper.cs index af68a7c32a..48e3590990 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHelper.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHelper.cs @@ -26,16 +26,91 @@ namespace Microsoft.AspNetCore.Authentication.Facebook } /// - /// Gets the user's name. + /// Gets the user's min age. /// - public static string GetName(JObject user) + public static string GetAgeRangeMin(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + return TryGetValue(user, "age_range", "min"); + } + + /// + /// Gets the user's max age. + /// + public static string GetAgeRangeMax(JObject user) { if (user == null) { throw new ArgumentNullException(nameof(user)); } - return user.Value("name"); + return TryGetValue(user, "age_range", "max"); + } + + /// + /// Gets the user's birthday. + /// + public static string GetBirthday(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + return user.Value("birthday"); + } + + /// + /// Gets the Facebook email. + /// + public static string GetEmail(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + + return user.Value("email"); + } + + /// + /// Gets the user's first name. + /// + public static string GetFirstName(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + + return user.Value("first_name"); + } + + /// + /// Gets the user's gender. + /// + public static string GetGender(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + return user.Value("gender"); + } + + /// + /// Gets the user's family name. + /// + public static string GetLastName(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + + return user.Value("last_name"); } /// @@ -51,30 +126,81 @@ namespace Microsoft.AspNetCore.Authentication.Facebook } /// - /// Gets the Facebook username. + /// Gets the user's location. /// - public static string GetUserName(JObject user) + public static string GetLocation(JObject user) { if (user == null) { throw new ArgumentNullException(nameof(user)); } - - return user.Value("username"); + return TryGetValue(user, "location", "name"); } - /// - /// Gets the Facebook email. + /// Gets the user's locale. /// - public static string GetEmail(JObject user) + public static string GetLocale(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + return user.Value("locale"); + } + + /// + /// Gets the user's middle name. + /// + public static string GetMiddleName(JObject user) { if (user == null) { throw new ArgumentNullException(nameof(user)); } - return user.Value("email"); + return user.Value("middle_name"); } + + /// + /// Gets the user's name. + /// + public static string GetName(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + + return user.Value("name"); + } + + /// + /// Gets the user's timezone. + /// + public static string GetTimeZone(JObject user) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + return user.Value("timezone"); + } + + // Get the given subProperty from a property. + private static string TryGetValue(JObject user, string propertyName, string subProperty) + { + JToken value; + if (user.TryGetValue(propertyName, out value)) + { + var subObject = JObject.Parse(value.ToString()); + if (subObject != null && subObject.TryGetValue(subProperty, out value)) + { + return value.ToString(); + } + } + return null; + } + } } diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs index 4ceda639cc..16b60e1dd4 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs @@ -71,6 +71,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppId))); } + if (string.IsNullOrEmpty(Options.AppSecret)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppSecret))); diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs index af82c6f9a7..ac6987f3df 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs @@ -24,7 +24,10 @@ namespace Microsoft.AspNetCore.Builder AuthorizationEndpoint = FacebookDefaults.AuthorizationEndpoint; TokenEndpoint = FacebookDefaults.TokenEndpoint; UserInformationEndpoint = FacebookDefaults.UserInformationEndpoint; - Fields = new List(); + Scope.Add("public_profile"); + Scope.Add("email"); + Fields.Add("name"); + Fields.Add("email"); } // Facebook uses a non-standard term for this field. @@ -57,6 +60,6 @@ namespace Microsoft.AspNetCore.Builder /// The list of fields to retrieve from the UserInformationEndpoint. /// https://developers.facebook.com/docs/graph-api/reference/user /// - public IList Fields { get; } + public ICollection Fields { get; } = new HashSet(); } }