Tag Archives: Facebook

Programmatically Updating SharePoint User Profiles with Facebook Data

While giving my demo at SharePoint Saturday Boston last weekend, I showed how to populate a Contacts list in SharePoint with data from the currently logged in user’s Facebook profile. An audience member posed a question about user profiles in SharePoint and how data from Facebook could also be used to populate them. Though I had never considered the potential applications of doing this (one might not think to leverage SharePoint user profiles in a public-facing scenario), it is technically straightforward to do.

Prerequisites

In order to surface Facebook profile information in a SharePoint user profile, you should have the following in place:

  • A My Site Host site collection deployed on the same web application where Facebook is configured as an identity provider.
  • User Profile properties configured to allow the user to edit values for the properties you wish to set/update programmatically.

Objective

In our scenario, we will take the following information from a user’s Facebook profile and use it to populate his/her SharePoint user profile:

  • Given name
  • Job title
  • Location
  • “About me” bio
  • Birthday
  • Profile picture

Our Starting Point

Upon initially configuring Facebook as an identity provider for SharePoint, a very bare bones user profile will appear when selecting “My Profile” from the welcome menu.

The profile page (person.aspx) shows the claims-encoded name for the user, and that’s about it:

The Code

The algorithm required to update a user profile for a user logged in via Facebook is the same as it is for any other SPUser; however, we will utilize the Facebook C# SDK to encapsulate calls to the Facebook Graph API to get the information we need. For demonstration purposes, I have this code wired up to a button click event handler in a SharePoint web part.

This code leverages JSON.NET to parse the JSON-formatted values returned by calls to the Facebook Graph API.

// Iterate through the Claims we are presented until we find the Facebook AccessToken
// and given name
IClaimsPrincipal claimsPrincipal = Page.User as IClaimsPrincipal;
claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;
foreach (Claim c in claimsIdentity.Claims)
{
    if (c.ClaimType.Equals("http://www.facebook.com/claims/AccessToken"))
    {
        // We will use this Claim to make all calls to the Facebook Graph API
        token = c.Value;
    }
    else if (c.ClaimType.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"))
    {
        // We will use this Claim to set the proper display name for the user
        givenName = c.Value;
    }
}

// Assuming we have the AccessToken, use it to access the user's Facebook profile
if (!string.IsNullOrEmpty(token))
{
    var client = new Facebook.FacebookClient(token);
    var me = (IDictionary<string, object>)client.Get("me");

    Guid siteId = SPContext.Current.Site.ID;
    Guid webId = SPContext.Current.Web.ID;

    // Assume the identity of the application pool - this account is configured as an
    // Administrator of my User Profile Service Application in Central Administration
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite site = new SPSite(siteId))
        {
            try
            {
                // Obtain a reference to the UserProfileManager for this SPSite
                SPServiceContext sc = SPServiceContext.GetContext(site);
                UserProfileManager userProfileMangager = new UserProfileManager(sc);

                SPUser currentUser = SPContext.Current.Web.CurrentUser;
                if (currentUser != null)
                {
                    // Get the current user's SharePoint profile
                    UserProfile profile = userProfileMangager.GetUserProfile(true);

                    // Update the display name and preferred name to match given name
                    profile.DisplayName = givenName;
                    profile[PropertyConstants.PreferredName].Value = givenName;
                    profile[PropertyConstants.Birthday].Value = (string)me["birthday"];
                    profile[PropertyConstants.AboutMe].Value = (string)me["bio"];
                                    
                    // Get the current job title
                    JsonArray work = me["work"] as JsonArray;
                    // Most recent/current employer stored in work[0]
                    JsonObject company = work[0] as JsonObject;
                    if (company.ContainsKey("position"))
                    {
                        JsonObject position = company["position"] as JsonObject;
                        profile[PropertyConstants.JobTitle].Value = (string)position["name"];
                        profile[PropertyConstants.Title].Value = (string)position["name"];
                    }
                                    
                    // Get the current location
                    JsonObject location = me["location"] as JsonObject;
                    string cityState = (string)location["name"];
                    profile[PropertyConstants.Location].Value = cityState;

                    // Get the user's current Facebook profile picture
                    // https://graph.facebook.com/[Facebook Profile ID]/picture?type=large
                    profile[PropertyConstants.PictureUrl].Value = "https://graph.facebook.com/" + (string)me["id"] + "/picture?type=large";
                                    
                    // Commit all changes to the user's profile
                    profile.Commit();
                }

                lblOutput.Text = "<font color=green><b>User profile successfully updated.</b></font>";
            }
            catch (Exception ex)
            {
                lblOutput.Text = "<font color=red><b>" + ex.Message + "<br/>" + ex.StackTrace + "</b></font>";
            }                            
        }
    });
}

The Outcome

After executing this code, the user’s SharePoint profile looks a lot more complete!

One Final Thing

My demos include a basic “status update” web part that allows a user to type a status message in a SharePoint web part. With a few additional lines of code, we can update the “What’s happening?” text bubble to include the text of this status update as well:

SPServiceContext sc = SPServiceContext.GetContext(site);
UserProfileManager userProfileMangager = new UserProfileManager(sc);
UserProfile profile = userProfileMangager.GetUserProfile(true);
profile[PropertyConstants.StatusNotes].Value = txtStatus.Text;
profile.Commit();

Now whenever I post a status update, it will update both my Facebook profile and my SharePoint profile!

Slides, Code, and More for my SPSBOS Session

Thanks to everyone who came out to SharePoint Saturday Boston yesterday! Once again, the organizers put together an outstanding event with well over 300 developers, administrators, and end users in attendance. Thanks, also, to all the sponsors who help to make such great events possible.

I had the great privilege of being able to speak at this event. I would like to extend a special thank you to everyone who attended my session on Claims-Based Identity, Facebook, and the Cloud yesterday morning. There were lots of great questions and discussions! Thanks to all of you for your participation. I hope you enjoyed the session and found the information presented to be valuable.

Below are links to my presentation, code, PowerShell script, and CloudShare environment. Additional background information can be found in my blog post Beyond Authentication: Deeper Facebook Integration with SharePoint.

Download presentation as .pptx

Web parts, source code, site template, and required certificates

PowerShell script to configure Azure ACS trusted identity provider

If you would like a copy of the CloudShare virtual machine I used for my demos, follow this link to obtain a 14-day free trial of CloudShare (if you don’t already have an account) and access a copy of the environment. I used the VM called SharePoint 2010 Enterprise SP1 for my demos. If you would like to know more about CloudShare (I love CloudShare!), please contact me.

Also, to take full advantage of the functionality shown in this demo, I strongly encourage you to sign up for a 90-day free trial of Windows Azure. This will give you access to the AppFabric Access Control Service (ACS) capabilities I demonstrated. If you already have a Windows Azure account, or if you choose to convert your trial to a full-blown account, the ACS features are free through December 1, 2012 (after this date, the charge will be $1.99 for every 100,000 transactions).

If you have any questions or issues deploying or running the code and/or scripts above, feel free to leave a comment below. Thanks again to everyone for such a fantastic event!

Beyond Authentication: Deeper Facebook Integration with SharePoint (with code!)

I had the privilege of speaking at SharePoint Saturday in Virginia Beach yesterday. This event is of particular significance each year within the community because the first ever SharePoint Saturday was held in Virginia Beach back in 2009 and SPSVB is seen as the “kickoff” for a new year of SharePoint Saturdays. As always, I learned so much at this event and had a great time meeting with and getting to know many of the speakers, volunteers, and attendees. I would like to thank each person who gave me 70 minutes of their time yesterday to learn more about Claims-based identity in SharePoint 2010 and see how we can do more than just log in to SharePoint with Facebook. I would especially like to thank those who provided me with feedback. I plan to refine and improve this presentation for future community events, so stay tuned!

Below is the slide deck I used in my session. In addition to introducing Claims-based identity in SharePoint 2010 and detailing some of the things to look out for when working with Claims, it illustrates how to configure Windows Azure AppFabric’s Access Control Services to support logging in to SharePoint with Facebook accounts. More detailed information about this process can be found here.

But we can do more than just log in…

Much of the feedback I received yesterday related to the various demonstrations of how I used the Facebook C# SDK to surface data from Facebook in SharePoint (and vice versa) using Facebook’s Graph API. When it comes to the potential of the integration of Facebook and SharePoint, the sky is truly the limit. The AccessToken claim that Facebook includes in the OAuth token it generates will provide your application with access to any data it requests (while still obeying the privacy settings you and everyone in your friends list have in place).

More about the Facebook C# SDK

You can download the Facebook C# SDK here. The “Assemblies only” version is all you need to get started, although it is interesting and informative to be able to see the source code. (Having access to the source code helped me troubleshoot this issue as well.) The SDK includes support for .NET Framework 3.5/4.0 and Silverlight. Obviously, we must use the .NET Framework 3.5 version in conjunction with our SharePoint development. The project is well documented and includes some great examples here and at Prabir’s blog here.

Data returned from the Facebook Graph API is in JSON format. To parse this data quickly and efficiently, my project includes the Json.NET framework.

If you download the source code for my demos here, you will see it includes a series of SharePoint project items. They include:

ClaimsWebPart

Largely based on this blog post, the Claims Web Part displays all of the claims included in the logged in user’s identity token in grid format. I added some Facebook-specific items in here for debugging purposes, such as displaying the user’s Facebook access token (parsed from the identity token), then using that token and the Facebook C# SDK to get the user’s current city, hometown, and Facebook user name.

The Claims Web Part is a great troubleshooting/debugging tool for developers and administrators who are new to working with Claims. It is a quick and easy way to verify the claim rules you configured when creating your Trusted Identity Provider are behaving the way they should.

SilverlightToFacebook

In my demo, a Silverlight application interfaces with the user’s webcam and saves snapshots to a SharePoint document library (hat tip to MossLover for that code). This class contains an event receiver that then takes those photos added to the SharePoint document library and uploads them to Facebook.

SPSVBDemos

This web part is the “dashboard” I used to do a handful of quick proof-of-concept demos, including the following:

  • Changing the display name of the currently logged in SPUser to match the name claim returned by Facebook (instead of the user’s email address or Claims-encoded username).
  • Adding information from the user’s Facebook profile (name, city, birthday, employer, job title, etc.) to a contacts list.
  • Populating a calendar list with recurring events for all of your friends’ birthdays (based on friends whose privacy settings allow sharing of this information).
  • Uploading a video from the file system to the user’s Facebook profile.

StatusUpdateWebPart

This web part allows the user to update his/her Facebook status directly from SharePoint. Optionally, the user may also include a link (with image, caption, description, etc.) with each status update.

WeatherWebPart

This web part determines the current user’s city from his/her Facebook profile, then constructs a request to the URL-driven Weather Underground API to retrieve the current weather conditions in that city. While many of these web parts may only have value in demos, I believe this web part represents a meaningful way for SharePoint site owners to provide a nice personalization experience to end users who log in to SharePoint with Facebook accounts.

Site Template

I also created a site template (SPSVB.WSP) that contains the custom lists and web parts I used in my demo. It is included in the code download.

Thanks again to everyone who helped to make SharePoint Saturday Virginia Beach such a great success! If you have any questions or suggestions about this code, please feel free to post them in the comments.

Download

SPSVB web parts, source code, site template, and required certificates to configure SharePoint trust for Facebook

Required Trust Relationships for the Facebook C# SDK in SharePoint 2010

I recently started using the Facebook C# SDK from CodePlex in my efforts to link SharePoint 2010, Claims-Based Identity, Azure ACS, and Facebook into one killer demo for my presentation on Claims-Based Identity that I will be giving at SharePoint Saturday Virginia Beach next month.

Without giving too much away, I intend to leverage the AccessToken input claim type provided by Facebook through Azure ACS to reach back into the user’s Facebook profile and obtain more information about the user who has just logged in to SharePoint from Facebook.

After rushing into coding a new web part (as any good developer would), I immediately encountered the following exception upon deployment:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
at FluentHttp.HttpHelper.OpenRead()
at Facebook.FacebookClient.Api(String path, IDictionary`2 parameters, HttpMethod httpMethod, Type resultType)

This error was met with the following corresponding entry in the Event Viewer:

In order to resolve this error, it is important to remember that SharePoint 2010 maintains its own certificate store, where separate trusts must be configured and maintained. Even though the root of the certificate chain may already be trusted everywhere else, you will receive this error unless an explicit trust is configured for SharePoint in Central Administration (or through PowerShell).

After much trial and error, I discovered that two trusts must be configured to support Facebook. First, go to the DigiCert Root Certificate site and download the following certificates as .cer files:

  • Under Root Certificates: DigiCert High Assurance EV Root CA
  • Under Intermediate Certificates: DigiCert High Assurance CA-3

Now that you are armed with these two .cer files, go to Central Administration. Go to Security, then under “General Security,” choose Manage Trust.

For each of the two .cer files, perform the following steps:

  1. From the ribbon, select New.
  2. In the “Establish Trust Relationship” dialog that appears, give each certificate a friendly name. In the “Root Authority Certificate” section, press Browse… and navigate to each .cer file.
  3. Press OK.

Perform an IISRESET after adding both certificates, and you should be ready to leverage the Facebook C# SDK from SharePoint 2010. Happy coding, and I hope to see you at SPSVB on January 7th!