1

We have implemented Salesforce SSO, which allows B2C customers to self-register or login via the SSO endpoint (authenticating via a predefined Connected App).

The requirement is - when a user register or login successfully, an Apex logic should set a custom Boolean field to true in the user record.

I know there is this ConnectedAppPlugin Class that allows us to inject custom logic. But the three methods, i.e. authorize(), refresh(), and customAttributes(), seem not the logical place to inject this "update a field in user object".

Where shall I put the custom Apex logic?

3

The ConnectedAppPlugin is exactly the right place for logic like that. It's the only piece of code that's called during the SSO flow.

A Login Flow comes to mind as another option, but unfortunately it cannot detect which connected app started it.

The method you can use depends on the settings of your Connected App. If you set it to self-authorize, then you'd need the customAttributes() method, if set to Admin pre-approved you can use authorize(), because authorize is not called if the Connected App is set to self-authorize.

Since the customAttributes() method is called every time, that would be the easiest place.
customAttributes() is formally used to provide additional attributes in the UserInfo response, but that doesn't mean we cannot do other stuff. Just make sure you return the formulaDefinedAttributes (those contain values that you set in the Custom Attributes configuration of the Connected App). If you want, you can of course take the opportunity to add additional attributes.

global override Map<String, String> customAttributes(Id userId, Id connectedAppId, Map<String, String> formulaDefinedAttributes, Auth.InvocationContext context) {
    // Explain the reason you are using DML here to set the boolean, f.i.:
    // We set YourBoolean__c for reporting purposes, to keep track of 
    // the percentage of users logging in through our connected app, compared to the regular login method.      
    update new User(
            Id = userId,
            YourBoolean__c = true
    );

    return formulaDefinedAttributes;
}

If you want to use the authorize() method, you can do the same, but then you just need to return the isAdminApproved boolean (or return a boolean based on your own logic of course).

    global override Boolean authorize(Id userId, Id connectedAppId, Boolean isAdminApproved, Auth.InvocationContext context) {
    update new User(
            Id = userId,
            YourBoolean__c = true
    );

    return isAdminApproved;
}
  • I was considering to put the new logic into CustomAttributes(), but it's a hidden surprise when readers see a DML is made inside this method. If there is no better place, perhaps we can only accept it :(. – Xi Xiao Jun 30 '20 at 9:33
  • It could be a surprise indeed, but that is why they invented //comments ;) I'll add it to my answer for completeness – Folkert Jun 30 '20 at 9:52

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.