Using Azure ACS to Sign In to SharePoint 2013 with Facebook

For those of you who have seen me speak (or read my blog posts) about Claims-based identity, SharePoint 2010, Facebook, and the cloud, you already know that Windows Azure Access Control Service (ACS) can be used to set up identity providers such as Windows Live ID, Google, Yahoo!, and Facebook in SharePoint 2010 through the magic of Claims.

In this blog post, I am pleased to report that all the steps to follow to enable this integration with SharePoint 2010 also work with SharePoint 2013!

For those who are unfamiliar with this integration, I will cover the steps at a high-level below with screenshots from SharePoint 2013. Keep in mind the process to follow is the same for SharePoint 2010.

Prerequisites

Procedures

Setting up this integration requires configuration steps to be performed in three different places:

  1. Within Facebook, an application must be created that supports “Website with Facebook Login.”
  2. Within the Azure ACS management portal, a new Identity Provider (IP), Relying Party (RP) application, and Rule Group must be created to inform Azure ACS about:
    a. The Facebook application created above.
    b. The SharePoint environment to be configured with Azure ACS integration below.
  3. Within SharePoint, we must create a new web application with Claims (in SharePoint 2013, Claims is the default authentication mechanism) and configure it to point to our Azure ACS setup as a Trusted Identity Provider.

We must also inform both Azure ACS and SharePoint about the SSL certificate that will be used to sign the SAML tokens containing a user’s claims. This is done by uploading the X.509 certificate into the Azure ACS management portal and telling SharePoint to trust this certificate (via the New-SPTrustedRootAuthority and New-SPTrustedIdentityTokenIssuer cmdlets which we will execute later on). In a demonstration environment, I use a self-signed certificate made via the makecert command. In production, you would obviously want to use a legitimate SSL certificate.

Facebook Application Setup

Within the Facebook Developers application, click Create New App.

Give the app a Name and a Namespace. Click Continue.

After passing the Captcha check, select Website with Facebook Login in the next screen and enter the URL to your Azure ACS Service Namespace (e.g., https://{your namespace}.accesscontrol.windows.net). Click Save Changes.

Take note of the App ID and App Secret values that appear at the top of this screen. You will need to use these to configure Azure ACS to leverage this application. That’s all we need to do within Facebook!

Azure ACS Setup

Within Azure ACS, we must configure the following four things:

  1. Facebook as an Identity Provider.
  2. SharePoint as a Relying Party Application.
  3. Claims Rule Groups to determine how Claims are passed from the identity provider to the relying party application.
  4. The Token Signing Certificate that Azure ACS will use to prove that it is indeed the issuer of the SAML token that SharePoint receives.

Identity Provider

From within your Azure ACS management portal (e.g., https://{your namespace}.accesscontrol.windows.net) and select Identity providers from the Trust relationships section in the left navigation. In the next screen, click Add.

In the next screen, choose Facebook application and click Next.

In the next screen, enter the Application ID and Application secret values from the Facebook application you created above. You should also provide a Display name (for use within the ACS management portal) and a comma-separated list of Application permissions (note that email is the only required permission to enable Facebook users to sign in to SharePoint). You can, however, request additional permissions to do lots of fun and exciting things. Those permission strings are defined here.

You do not need to specify values for Login link text or Image URL unless you plan to configure more than one Azure ACS identity provider to use with SharePoint. If you have already configured your Relying party applications within Azure ACS, you may select them at the bottom of this screen. Otherwise, we will configure SharePoint as an RP in the next step.

Press Save to save changes.

Relying Party Application

From within your Azure ACS management portal (e.g., https://{your namespace}.accesscontrol.windows.net) and select Relying party applications from the Trust relationships section in the left navigation. In the next screen, click Add.

In the next screen, provide a name for the relying party application (I often just use the fully-qualified domain name of my SharePoint web application) and choose to Enter settings manually. In the boxes below, enter the following values:

  • Realm – URL of your SharePoint web application (note that a URN can also be entered here and, in many cases, is the preferred approach)
  • Return URL – URL of your SharePoint web application + /_trust – this is the endpoint for SharePoint’s STS, which is where Azure ACS will send the SAML token it creates
  • Token format – SAML 1.1
  • Token lifetime – enter a value greater than the default 600 seconds (Wictor Wilen gives a great explanation why here)

In the Authentication Settings section, select the Identity provider you configured above and choose to Create a new rule group. Under Token Signing Settings, choose whether to Use service namespace certificate (if you have already configured a certificate within Azure ACS) or Use a dedicated certificate if you would like to use a different X.509 certificate exclusively for this relying party application.

Click Save to save changes.

Rule Group

From within your Azure ACS management portal (e.g., https://{your namespace}.accesscontrol.windows.net) and select Rule groups from the Trust relationships section in the left navigation. In the next screen, click Default Rule Group for {your web application}.

Note that no rules are added by default. Click Generate and select the identity provider you created above.


Click Generate to generate Claims rules for the 5 values Azure ACS can obtain from a logged in Facebook user:

  1. AccessToken – the Facebook Graph API access token
  2. emailaddress – the email address associated with the user’s Facebook profile
  3. expiration – the expiration date/time of the AccessToken granted above
  4. name – the Facebook user’s display name
  5. nameidentifier – the Facebook user’s unique profile ID (integer)

Press Save to save the rules.

Upload Token Signing Certificate

If you haven’t already, you will need to configure Azure ACS to utilize an X.509 certificate to digitally sign the tokens it generates. Optionally, you can also specify certificates to use for token encryption and decryption. For the purposes of this demonstration, I generated a self-signed certificate using the makecert utility. DO NOT DO THIS IN PRODUCTION! I then uploaded this certificate by going to the Certificates and Keys link under Service settings in the ACS management portal.

cert1

Click Add to upload your certificate. This page allows you to specify where the certificate should be used, what type of certificate it is, and how to make it the primary token-signing certificate. It even includes the specific makecert command you need to run to generate a self-signed certificate (again, I cannot overemphasize how important it is that you NOT use a self-signed certificate in production!)

cert2

That’s all we need to do within Azure ACS!

SharePoint 2013 Setup

Within SharePoint, we must do the following:

  1. Create a new web application using Claims-based authentication (the default mechanism in SharePoint 2013).
  2. Configure Azure ACS as a new Trusted Identity Provider for that web application and tell SharePoint to trust the certificate Azure ACS uses to sign its SAML tokens.
  3. Set a User Policy within the web application to allow users who log in via the Trusted Identity Provider to have access to the site.

New Web Application

From SharePoint 2013 Central Administration, create a new web application. Unlike SharePoint 2010, SharePoint 2013 does not prompt you to choose between Classic and Claims-based authentication. Claims is the default (hooray)!

Make sure the host header matches the host header for the Return URL specified in the Azure ACS relying party application setup. Enable Integrated
Windows Authentication with NTLM at this step. You’ll notice no Trusted Identity providers exist at this point.

Enjoy the friendly new progress messages in SharePoint 2013:

Create a new site collection at the root of the web application and choose a Windows identity for the primary Site Collection Administrator.

Configure Azure ACS as a new Trusted Identity Provider

In order to enable us to select Azure ACS as a trusted identity provider for the web application, we need to run some PowerShell. The script to run appears below.

$realm = "http://intranet.contoso.com"
$signinurl = "https://dannyjessee.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fintranet.contoso.com%2f"
$certloc = "C:\dannyjessee.cer"
$rootcert = Get-PfxCertificate $certloc
New-SPTrustedRootAuthority "Danny Jessee Azure ACS" -Certificate $rootcert
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certloc)
$map1 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "Email" -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" -IncomingClaimTypeDisplayName "Display Name" –LocalClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
$map3 = New-SPClaimTypeMapping -IncomingClaimType "http://www.facebook.com/claims/AccessToken" -IncomingClaimTypeDisplayName "Access Token" -SameAsIncoming
$map4 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" -IncomingClaimTypeDisplayName "Name Identifier" –LocalClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"
$map5 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.microsoft.com/ws/2008/06/identity/claims/expiration" -IncomingClaimTypeDisplayName "Expiration" -SameAsIncoming
New-SPTrustedIdentityTokenIssuer -Name "Facebook" -Description "Facebook" -Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map1,$map2,$map3,$map4,$map5 -SignInUrl $signinurl -IdentifierClaim $map1.InputClaimType

This script performs the following actions:

  1. Establishes a trust relationship between SharePoint and the Azure ACS token signing certificate (this is the equivalent of going to Security > Manage trust and uploading this certificate in Central Administration).
  2. Sets up the claim rules to pass the claims returned from Azure ACS to the SharePoint STS at the _trust endpoint (in some cases, these claims need to be mapped to different claim type URIs to avoid collisions with claims provided by the SharePoint STS).
  3. Creates a new trusted identity provider associated with the appropriate realm, certificate, claims mappings, and sign in URL (this value can be obtained by going to Application integration under Development in the Azure ACS management portal, then selecting Login pages).

Some things to keep in mind as you modify this script to run in your environment:

  • Ensure the value for $realm matches the realm value used when creating the relying party application within Azure ACS.
  • Ensure the X.509 certificate used here is the same as the token signing certificate used when creating the Relying Party application within Azure ACS.
  • Ensure the value for $signinurl is set properly for your SharePoint web application.

Run this PowerShell script from the SharePoint 2013 Management Shell (as an Administrator). If you don’t see red text, you’re doing alright!

Return to the list of web applications in SharePoint 2013 Central Administration. Select the web application and press Authentication Providers.

Choose the appropriate zone and scroll down. Facebook should now appear in the list of trusted identity providers:

Select Facebook and press Save. You have now configured Azure ACS as a new trusted identity provider, and SharePoint knows it can trust SAML tokens signed with your Azure ACS token-signing certificate.

Set User Access Policy

In order for users to access your SharePoint 2013 site once they have authenticated via Facebook, we must grant them the appropriate level of authorization. To do this, I recommend setting a “Full Read” policy for all users who authenticate to SharePoint via our “Facebook” trusted identity provider. Start by selecting the web application in Central Administration and go to User Policy.

Choose Add Users, then select the appropriate zone (All zones) and press Next.

Select the address book icon beneath the Users text box to bring up the Select People and Groups dialog.

Select All Users, then choose All Users (Facebook). Press Add to select the group.

Check the box for Full Read in the permissions section and press Finish.

The new policy is now displayed at the bottom of the list.

With that, our SharePoint configuration is complete! We are now ready to have our users sign in to SharePoint 2013 with Facebook.

Signing in to SharePoint 2013 with Facebook

Navigate to the home page of the web application. The default sign in page will appear.

Choose Facebook from the drop down list. The user will be redirected (through the Azure ACS portal) to a Facebook-hosted login page.

Enter your Facebook credentials and press Log In. The first time a user attempts to log in to your SharePoint site with Facebook, he or she will be prompted to grant the Facebook application access to the user’s basic information and email address (this is based on the permissions we set up when we initially defined the Facebook identity provider in the Azure ACS management portal).

Press Go to App. The user should be redirected back to Azure ACS, which then redirects the user back to SharePoint…logged in with Facebook credentials!

Note the user’s display name is the email address associated with the user’s Facebook account. This is because we set EmailAddress as the IdentifierClaim in the PowerShell script we ran to configure Azure ACS as a trusted identity provider.

I know this is a TON of information to put in a single blog post, so feel free to post any questions in the comments!

  • Ken Collins

    You are correct; a bunch of information here. Thank you for sharing. I almost have it working after some extensive work trying to understand the Certificate stuff. Still not sure I have those steps done correctly. Anyhow I have it configured and have two questions: 1) what does the +/_trust do ? 2) My error is Value cannot be null Microsoft.SharePoint.Utilities.SPUtility.FormatAccountName(String provider, String user)

    • http://dannyjessee.com/blog Danny Jessee

      Ken – the _trust URL is SharePoint’s STS. When you specify this location as the Return URL in ACS, SharePoint takes the claims from ACS and uses the claims mappings you configure in the PowerShell script to determine which claims get packaged in the token built and signed by SharePoint.

      Can you tell exactly what is generating the error message you are seeing? Anything in the ULS logs? I did a little bit of searching but didn’t find anything that didn’t involve Forms Based Authentication (which this setup obviously does not). Best of luck!

      • Doug T

        @Danny is there a way to segregate users once they get validated from FB or linkedin ? for eg
        user1(walmart) once authenticated I want the user to go to a walmart
        site

        user2(target) once authenticated i want the user to go to target site/page

        any idea how to accomplish that ?
        TIA

        • http://dannyjessee.com/blog Danny Jessee

          Hi Doug – I’ve never had to do anything like that before, but assuming the users have claims to identify them as either “walmart” or “target,” this should be doable. You could write code in a custom sign-in page to check for the presence of one of those claim values after the user has authenticated and redirect them accordingly. There are some pretty good tutorials out there involving how to build custom sign-in pages.

          Alternately, if users know they are “walmart” or “target,” you could create separate trusted identity providers for each of them and give the user the choice of which one to use when signing in using the default sign-in page. Good luck!

          • Doug T

            Thanks Jesse,
            let me try to first your first suggestion about saving tokens

  • Ken Collins

    Key to this exercise is know and understand how Certificate stuff works. That was my problem. Check your certificates to make sure they match on both sides. Azure and SharePoint…BINGO! It worked like a champ. Thank you Danny.

    • http://dannyjessee.com/blog Danny Jessee

      No problem. Glad to hear you got everything working! Your feedback inspired me to update this post a bit today. I tried to place a little more emphasis on the role of the certificate, where it needs to go, and how the trust relationship is configured between SharePoint and Azure ACS. It is indeed fundamental to making this work!

  • http://twitter.com/ranjanAshish Ashish Ranjan

    Excellent Article…I had not read the SP2010 version, but did not have to read that to understand this. Great Work. Thanks Danny

  • http://Ubaid.tk/Send-free-sms/ Mohamed Ubaidullah

    Danny,

    Is it possible to do this without using Azure ACS? I am specifically looking for non-commercial alternatives.. Also, I assume it should work for SPF 2010 as wellL

    • http://dannyjessee.com/blog Danny Jessee

      Yes, it can be done without Azure ACS but it requires a lot more work on your part. You need to build your own STS that knows how to reach Facebook, ensure the user has signed in there, obtain claim information from Facebook, and package and sign SAML tokens. (As you can see, Azure ACS really simplifies everything, and it’s free!) If you do want to go the non-commercial route, Travis Nielsen has written up a great blog post about how to do this same integration without Azure ACS here: http://blogs.perficient.com/microsoft/2010/12/sign-into-sharepoint-2010-with-facebook-using-a-custom-sts/

      And yes, these solutions will work in Foundation as well.

  • Rob Sked

    Hi Danny,

    If I already have permission groups set up within SP2013 do I still need to set up the user access policy?

    I have recently used ACS to add Windows Live, and I can add and resolve users, but when I then browse and login, I get the “Sorry, this site has not been shared with you” message – despite having just added the user to the group.

    Would appreciate your thughts.

    Cheers,

    Rob

    • http://dannyjessee.com/blog Danny Jessee

      Rob – Thanks for commenting! Hopefully I can help. How are you granting that group access to the site? Do you have another authentication provider (e.g., Windows) set up on the same site? Someone from the ACS identity provider should serve in a Site Collection Administrator role as well. (As a side note, does it work if you DO set that Full Read policy at the web application level?)

      More questions than answers from me, I know, but hopefully we can get to the bottom of it. Personally, I’ve always set the Full Read policy since an internet-facing site would need to be accessible to any user coming in from the ACS identity provider.

      • Rob Sked

        Hi Danny, thanks for replying, hopefully you won’t be bored with the following waffle :-)

        If I apply the Full Read Policy, I can access the site. The problem is, if I then try to use an alternative Windows Live ID account, that immediately get’s access too.

        In terms of the setup – I have a site collection, that is extended (to a different URL) for external access.

        I have set up the ACS server, and added it to both the Default zone (for my internal users) and my Internet zone (for external users on the extended webapp).

        For internal users, they are authenticating using standard Windows logins (NTLM). I have had to also include the trusted identity provider in order to be able to resolve the Windows LiveID logins when adding them to the site.

        Groups on the actual site – I have standard Member, Owners and Visitor group. The process that I’ve been following has to be go to the internal site, and then add in the UID for the LiveID account. When it resolves, I select the UPN account, and this is then added to my “Visitors” permission group.

        I should then be able to access my external site, login with the proper e-mail address for the LiveID, and then get access to the site – this is where is stop working, and I get the “Sorry you do not have access”.

        There *is* another identity provider set-up – this was when I was using the older msm.live.com service. But this is not ticked.

        When you say add in a user from the ACS provider as a site collection admin, what do you mean? If I look at current site collection owners for the internal site, both my local Windows account is added, as well as one of the service accounts (again, a windows service account).

        Hopefully this gives you a better over view of my setup?

        Cheers!

        Rob

        • http://dannyjessee.com/blog Danny Jessee

          Thanks for the additional info. When you refer to the “UID” of the Live account, I assume you’re referring to the “00000aaaaaaaa@live.com”-type identifier that is generated and not the user’s actual email address, correct? If so, are there multiple entries with the same value returned by the people picker when you enter the user’s Live UID? It is important that you choose the one that maps to the proper claim type (if you’ve mapped multiple claim types in your trusted identity provider, there will be multiple values returned here), and it has to match the claim value exactly (unless you built a custom claims provider, the people picker is not giving you true name resolution). Hope this helps!

          • justskeddy

            Hi Danny,

            After checking out a few blogs and chatting to
            Microsoft themselves, it turns out the using the UID type identifier is not the best way, as SP2013 is expecting a different type of UID.

            They are going to suggest it as a feature change, to make it more manageable.

            In the meantime, could I possible ask one more question? I’ve been able to get Google integrated successfully via ACS, but the display name in 2013 is showing up as http://www.google.com/accounts/o8/id?id=(very long string).

            Do you know if there is a quick way to change this to show the e-mail address?

            Cheers,

            Rob (same Rob as above!)

          • http://dannyjessee.com/blog Danny Jessee

            Rob – you can change the display name using either the object model or PowerShell. If you want to use the object model, you could do something similar to what I did in my “LinkedInNameChanger” near the bottom of this post: http://www.dannyjessee.com/blog/index.php/2012/02/using-linkedin-as-an-identity-provider-for-sharepoint-2010/

            You would obviously pull the emailaddress claim value instead of the givenname one.

            If you look at the comment thread below that post, you’ll see someone also found some code that handles this problem in a more automated way: http://www.codefornuts.com/2010/09/importing-user-profile-attributes-from.html

            Hope that helps!

  • Andres

    Excellent work Danny,

    It works like a charm. I was wondering though (forgive me if it is a dumb question), how can we restrict the log in to certain people. Obviously some sort of user mapping needs to happen the first time the user attempts to log in, but I am not sure how to go about it.

    Any help would be appreciated

    Ta
    Andres

    • http://dannyjessee.com/blog Danny Jessee

      Thanks! You can take one of two approaches. This post used a permissive approach (assuming it is a public-facing site, it makes sense to give everyone who comes in via Facebook a certain level of permissions since you don’t know who all your users will be). If you DO want to restrict permissions, though, you wouldn’t assign a Full Read policy the way I do here. You would instead have to specify exact claim values (e.g., email addresses associated with the Facebook accounts of the users to whom you wish to grant access). You can enter and select those values from the people picker and assign permissions to them the same way you would with other identity providers. Hope that helps!

      • Andres

        That was easy!, however it does have an odd behavior.
        Say I want to add ‘myfacebookaccount@provider.com’, when I look for it in the people picker, it will always return 5 matches, one of those is the actual account, which will allow the user to log in, the other 4 I don’t know what they are.. so in order to make sure that myfacebookaccount@provider.com is able to log in, I will have to grant access to all five matches, otherwise if I randomly pick one, chances are i will pick the wrong account and the user wont have access.

        It funny how you can type any occurrence like “sdfsfsw34432″ and that will still match to 5 ‘accounts’.

        Any thoughts on this? What will be the implications of granting access to all 5 matches?

        Thanks!

        • http://dannyjessee.com/blog Danny Jessee

          That behavior is by design. Unless you develop a custom claims provider, the people picker is “dumb.” It’s not actually looking up or “resolving” what you type in, it’s just allowing you to assign permissions to values for any of the 5 claim types you mapped with the New-SPClaimTypeMapping cmdlets: emailaddress, name, AccessToken, name, and nameidentifier. If you select one of the matches from the people picker and then mouse over it, you should see which of the 5 claim types your selection maps to (so you should never have to grant access to all 5). Hope that helps!

          • Pilsen

            Should have taken a closer look to the hover.
            Thanks a lot!

  • Antonio Longhitano

    Hi Danny,

    Thanks for the post, it works perfectly!! :)
    I have a question for you. I configured the Facebook login for the internal web app (e.g. http://sharepoint.domain.com)
    I need to do the same on to the extension of the same web app (e.g. https://sharepoint.domain.com).
    I added a new relying party on the ACS side and I added a new ProviderRealm in the existing Identity token issuer although when I access the https://sharepoint.domain.com and I try to sign in with Facebook it returns a 404 error.

    Thank you in advance for you help..

    Antonio

  • Pingback: Thursday, December 26, 2013 on #WindowsAzure | Alexandre Brisebois

  • Pingback: Sharepoint 2013, Azure ACS and Custom User Table | Nick's Blog

  • Carlos Gutierrez

    Hi, Excelent post!! I just love it!, I have a question, can this be done using Sharepoint online? instead of sharepoint on premises?

    Thanks a lot!!

    • http://dannyjessee.com/blog Danny Jessee

      Thanks, Carlos! Unfortunately, we cannot currently do this same integration with SharePoint Online. I have to imagine it’s only a matter of time before they offer this capability, though.

  • Pingback: Sharepoint 2013, Azure ACS and Custom User TableIOI Solutions

  • Blake

    Hello Danny, thank you for all the helpful information. I was wondering if you have any suggestions on how to use Google / Facebook / Twitter to sign-in to a sharepoint 2013 site WITHOUT using Azure ACS. I have followed this post you have http://dannyjessee.com/blog/index.php/2012/02/using-linkedin-as-an-identity-provider-for-sharepoint-2010/ and I was able to make that work. Unfortunately for me that post is using Oauth 1.0 and now Google uses Oauth 2.0. All the information I have found is using ACS to create the relationship between sharepoint and Google. Any information would be wonderful. Thanks again.

    • http://dannyjessee.com/blog Danny Jessee

      Good question! This is not something I have looked into lately, but when I get some time I may attempt to implement a proof of concept using the
      Google APIs Client Library for .NET. They have a write-up about how to use it in conjunction with OAuth 2.0 here: https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth

      Stay tuned…and let me know if you get something implemented before I do!

      • Blake

        Thanks. Sounds like a plan.

  • Pingback: IOI : Sharepoint 2013, Azure ACS and Custom User Table