Just in Time (JIT) Provisioning allows you to create new standard and portal user records in Salesforce when a user first logs in via an IDP (Identity Provider). So, how is this useful for managing large portals? If you are running a high volume Customer Portal in Salesforce, you may not want to create all the user records for each of your customers right from the onset since each user counts towards your license total. JIT provisioning allows you to create those user records when the customer first logs in so, you're only giving a license to those customers that are actually active in your portal.
There are three possible scenarios for which you could use JIT Provisioning for Portal Users;
- Match existing contact and account, create new user record.
- Match existing account, create new contact and user records.
- Create new account, contact, and user records.
The Axiom SSO Tool hosted on Heroku is a very useful app for testing your SSO configuration in Salesforce. This tool allows you to test your Salesforce configuration and make sure things are working as expected, irrespective of your IDP settings. (I will not be covering setting up your IDP here.)
So let's go thorugh the steps for configuring Single Sign-On in Salesforce and testing Just in Time Provisioning for those portal users.
1. Create a Customer Portal - I'm going to assume you already have a portal set up. If not, follow the instructions from the Salesforce documentation – Setting Up your Customer Portal.
2. Get Your Customer Portal Id – Setup >> App Setup >> Customize >> Customer Portal >> Settings. Click on the portal name to see the detail page below.
3. Get the Organization id - Setup >> Administrative Setup >> Company Profile >> Company Information
4. Download the Identity Provider Certificate - Go to http://axiomsso.herokuapp.com . (Use a different browser so that when testing the SSO login you won't get logged out of your Salesforce session.) Click the link for SAML Identity Provider & Tester. Then, download the Identity Provider Certificate .
5. Configure Single Sign-on in Salesforce – Go back to your Salesforce session and go to Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings

- SAML Enabled: True
- SAML Version: Default is 1.1. If you know the version your IDP uses, use that. Otherwise, select 2.0.
- User Provisioning Enabled: True
- Issuer: Axiom
- Identity Provider Certificate: Upload the Axiom certificate from the previous step
- SAML User ID Type: Assertion contains the Federation Id from the User object
- SAML User ID Location: User ID is in the NameIdentifier of the Subject Statement
NOTE: Later when you're ready to test your production IDP, you can change the Issuer name and upload a new certificate.
6. Generate a SAML Response - In your other bowser, go back to the Axiom SAML Identity Provider & Tester, and click the link for Generate a SAML Response. Fill in the fields as follows;
- SAML Version: Needs to match version selected in Salesforce SSO settings.
- Username OR Federated ID: This is a unique identifier for the portal user and used to locate an existing user. This value will be stored on the user record (User.FederationIdentifier) when a new user is provisioned. For testing creation of a new user, just enter whatever string value you want.
- User ID Location: Subject
- Issuer: Needs to match issuer name specified in Salesforce SSO settings.
- Recipient URL: This Salesforce.com Login Url displayed when you save the SSO settings.
- Entity ID: https://saml.salesforce.com (default value)
- SSO Start Page: http://axiomsso.herokuapp.com/RequestSamlResponse.action (default value)
- Start URL / Relay State:
- Logout URL:
- User Type: Portal (default is Standard)
- Organization Id: Org Id from Step 3
- Portal Id: Portal Id from Step 2
7. Enter JIT Provisioning Attributes - Just-in-Time provisioning requires the creation of a SAML assertion. The attributes in this assertion are critical details in matching/creating the records.
Here's the process as I understand it;
- Salesforce attempts to match the Federated ID in the subject of the SAML assertion (e.g. 12345) to the FederationIdentifier field of a existing user record.
- If a matching user record is found, JIT provisioning uses the attributes to Update the fields specified in the attributes.
- If a user with a matching user record isn't found, then Salesforce searches the contacts under the specified Account Id for a match based on LastName and Email.
- If a matching contact record is found, JIT provisioning uses the attributes to Update the contact fields specified in the attributes and then Inserts the new User record
- If a matching contact record isn't found, then Salesforce searches for the Accounts for a match based on Contact.Account or AccountNumber and Account Name.
- If a matching account record is found, JIT provision Inserts a new contact record and Inserts a new User record based on the attributes provided.
- If a matching account record isn't found, JIT provision Inserts a new account record, Inserts a new contact record, and Inserts a new User record based on the attributes provided.
Got it? If this seems really confusing then lets look at some more examples and their results in different scenarios.
Example 1: User record exists: Contact fields (eg LastName, Email) and User fields (eg Email, LastName, etc) are updated. User record does not exist, but contact record does: SFDC matches contact based on LastName and Email.New user record inserted. User record and contact record do not exist: New contact and user records are inserted. |
Contact.Account=00130000011Qx7i; |
In the above example, we can create new portal users and contacts given a hardcoded Account id. So, what if you don't know the id for the Account? Then you can search for it using the Account's Name and Account Number.
Example 2: User record exists: Account fields (eg Name, Owner), Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated. User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Name, Owner) are updated. New user record inserted. User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted. User record, contact record, and account record do not exist: New account, contact, and user records are inserted. |
Account.AccountNumber=9999; |
Note that in the above example, an owner Id is required to create a new account record.
Now what if you don't want JIT provisioning to create new account records or you don't have Account details in your IDP. Then you can leave out the account attributes altogether.
Example 3: User record exists: Contact fields (eg LastName, Email), and User fields (eg Email, LastName, etc) are updated. User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. New user record inserted. User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted. User record, contact record, and account record do not exist: Process does not insert any new records because an account is needed to create a contact and portal user record.
|
Contact.LastName=PortalUser3; |
The examples above show only the minimum attributes required. However, you can include additional attributes which correspond to standard fields on the User, Contact, and Account records. You can even include custom fields though only if they are a text field. You can get a full list of standard user attributes here and contact/account attributes here.
Example 4: User record exists: Contact fields (eg Phone, CustomField__c, etc), and User fields (eg Title, CustomField__c, etc) are updated. User record does not exist, but contact record does: SFDC matches contact based on LastName and Email. Account fields (eg Description, CustomField__c, etc) are updated. New user record inserted. User record and contact record do not exist: SFDC matches account based on AccountNumber and Name. New contact and user records are inserted. User record, contact record, and account record do not exist: New account, contact, and user records are inserted. |
Account.AccountNumber=9999; |
8. Generate the SAML Assertion – Click the Request SAML Response button.
9. Login – If everything has been configured correctly and login is successful, you should be directed to the Customer Portal's home page. If some error has occurred, you'll be redirected to the Custom Error URL you defined in the Salesforce SSO settings. Check the URL for error codes that might help you troubleshoot.
10. Confirm – Back in Salesforce verify the records have been created successfully.
Troubleshooting
Here are answers to a few common errors;
- INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY – Translation: you probably used an invalid id for either the User.ProfileId, Contact.Account or some other id field.
- CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY – Check the error description to see if this refers to the contact or the account. Check for validation rules that might be preventing record creation.
Another helpful tool is the SAML Assertion Validator (Setup >> Administrative Setup >> Security Controls >> Single Sign-On Settings). To use this tool, copy the Plain Text SAML Response from Step 8 and paste into the validation tool. It will run through the generated assertion and check for any errors.
Related Resources:
About Just-in-Time Provisioning for SAML
Just-in-Time Provisioning for Portals