1

I'm trying to set up Facebook SSO for a Salesforce customer community, and keep running into this error:

error message

This is the url of the error: https://volunteer.madd.org/_nc_external/identity/sso/ui/AuthorizationError?ErrorCode=NO_ACCESS&ErrorDescription=Unable+to+find+a+user&ProviderId=0SO0G0000008OLi&startURL=%2Fs%2F#=

The customer community does not allow users to self-register, so I've created a customer community user with the same name and email address as the Facebook account, so I'm not clear why the user can't be found.

Here is the SSO handler code I have:

global class SocialRegHandler implements Auth.RegistrationHandler{

private static final String ORG_SUFFIX = '.sso.badge.org';
public static final String DEFAULT_ACCOUNTNAME = 'MADD';
public String communityId = Network.getNetworkId();

global boolean canCreateUser(Auth.UserData data) {
System.debug('canCreateUser was called for ' + (data != null ? data.email : 'null'));
Boolean retVal = (data != null 
        && data.email != null
        && data.lastName != null
        && data.firstName != null);

System.debug('data.username='+data.username);
System.debug('data.email='+data.email);
System.debug('data.lastName='+data.lastName);
System.debug('data.firstName='+data.firstName);

return retVal;
}

global User createUser(Id portalId, Auth.UserData data){
if(!canCreateUser(data)) {
    if(data.email != null){
        User u = [Select Id , username from User where email =: data.email];
        return u;
    } else {
        return null;
    }

}

// Is this a Community Context?
if(data.attributeMap.containsKey(communityId)) {
    System.debug('Registering Community user: ' + data.email);

    // To keep things modular, we're creating the PersonAccount in a separate method
    // Id contactId = createPersonAccountContact(data);
    Contact c = new Contact();
    c.LastName = data.lastName;
    c.FirstName = data.FirstName;
    c.Email = data.email;
    insert c;

    // You'd likely use other logic to assign the Profile
    Profile p = [SELECT Id FROM profile WHERE name='MADD Customer Community User'];

    // Keeping it modular, we initialize the user in another method
    User u = createUser(data,p);

    u.contactId = c.id;
    return u;
} else {
    //This is not a community, so we Assign an internal profile
    Profile p = [SELECT Id FROM profile WHERE name='Standard User'];

    // Keeping it modular, we initialize the user in another method
    User u = createUser(data,p);

    return u;
}
}


global void updateUser(Id userId, Id portalId, Auth.UserData data){
System.debug('Update User called for: ' + data.email);

User u = new User(id=userId);
u.email = data.email;
u.lastName = data.lastName;
u.firstName = data.firstName;
update(u);
}

private Id createPersonAccountContact(Auth.UserData data) {
    Account person = new Account();
    person.LastName = data.lastName;
    person.FirstName = data.FirstName;
    person.personEmail = data.email;
    person.RecordTypeId = [Select Id From RecordType 
                            Where SobjectType='Account' 
                              AND isPersonType=true LIMIT 1].id;

    insert person;

    System.debug('Person Account created for ' + data.email + ' id=' + person.id);

    /**
     * This next step is necessary to get a valid contact Id,
     * it won't exist until the PersonAcct is saved

    Account a = [Select PersonContactId From Account Where Id = :person.Id];

    return a.PersonContactId; 

}
**/
/**
 * Create and initialize the User but don't save it yet
 * 
 * @param data - the provided User context from FaceBook
 * @param p - the Profile we are going to assign to this user
 * 
 * @return User that has been initialized but not Saved
 **/ 
private User createUser(Auth.UserData data, Profile p) {
    User u = new User();
    u.username = data.email + ORG_SUFFIX;
    u.email = data.email;
    u.lastName = data.lastName;
    u.firstName = data.firstName;
    String alias = data.firstName + data.lastName;

    //Alias must be 8 characters or less
    if(alias.length() > 8) {
        alias = alias.substring(0, 8);
    }
    u.alias = alias;
    u.languagelocalekey = UserInfo.getLocale();
    u.localesidkey = UserInfo.getLocale();
    u.emailEncodingKey = 'UTF-8';
    u.timeZoneSidKey = 'America/Los_Angeles';
    u.profileId = p.Id;
    return u;
}    
}

And here are the settings of the Facebook app:

Facebook app settings

I've reviewed all the documentation and related posts I could find, and I'm still left with a few questions:

  1. Is there anything in the above code I need to change in order to make the SSO work with a community? Or is there any reason it wouldn't be able to find a user with the same email address?
  2. Does the website URL on the Facebook app need to be the community login page (www.community.com/login) or the existing user linking url with the community url as a string append (https://login.salesforce.com/services/auth/link/00DF00000006xCGMAY/Facebook?community=http%3A%2F%2Fwww.community.com)?
  3. Do I need to configure SAML Single Sign-On to enable SSO for a community?
  • 1
    Do you have the debug logs for a run of this? – Adam Michael Daw Mar 2 '17 at 20:20
  • It's too big to past here, so I added it to a public google doc – TheDevAdmin Mar 2 '17 at 23:54
  • Hmmm - don't actually see the error in there. Can you share a screenshot of the error/page? – Adam Michael Daw Mar 3 '17 at 0:29
  • @AdamMichaelDaw I added the screenshot as well as the URL of the error to the original post. I also didn't see any error in the debug log, which makes me wonder if the issue is with the way the Facebook app is set up. I've also included a screenshot of the Facebook app setup screen – TheDevAdmin Mar 3 '17 at 13:56
0

Most of the credit for this answer goes to RJ Hill from MapAnything, who helped me solve this IRL.

The issue was that the Facebook app, by default, does not return the email address of the logged in user. So Salesforce cannot find the existing user, because it requires a First Name, Last Name and Email to lookup existing users.

In order to call the requisite information, the User Info Endpoint URL needs to be updated to the following: https://graph.facebook.com/me?fields=id,name,email,first_name,last_name

  • I'm having a similar problem to what you described above, but attempting to register my user on the fly. Using Debug Logs, it doesn't appear that my Registration Handler is ever called. Is the website URL in your FB App (in the screenshot) still up-to-date? Or did you use your community login? – aj2taylo Apr 21 '17 at 19:13
  • @user3883 the url in my facebook app is still the same, without the community URL string append (that's not necessary). I'm not sure what your other question is. The handler I built is designed around the fact that all of the users using facebook to sign into the community are already registered as community users. – TheDevAdmin Apr 22 '17 at 0:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.