This video is all about working with Salesforce, including setting up an org with the Salesforce CLI and configuring Salesforce Identity.
Category: Uncategorized
Salesforce Identity videos
Over the last few weeks I’ve spent a fair amount of time working with Salesforce Identity. Salesforce Identity is a very capable offering and offers a fully functional and very configurable identity provider (IdP) at a very competitive price compared to other identity providers on the market. Part of this work has been show casing a number of elements of Salesforce Identity from setting it up as a developer, to working with email templates and translations. To scale it I’ve recorded it as videos and wanted to share them on the blog in case someone could learn from it.
I’ll be posting the videos over the next couple of days. I’ve recorded videos on the following topics:
- Working with Salesforce, including setting up and org, Salesforce CLI, configuring Salesforce Identity
- PoC on Preventing Sign-in / Sign-up Page Reload
- Internationalization (i18n) / Localization (l12n)
- Email Templates including translation
- MFA Enablement
The videos use two repositories I’ve created for the demos:
Single Sign On to Salesforce with Azure Active Directory B2C as the IdP through OpenID Connect
A customer reached out the other day as they were unable to make Azure Active Directory B2C work with Salesforce for single-sign-on using OpenID Connect (OIDC). They were seeing a No_Oauth_Token error and couldn’t make it work so they asked if I would look into it.
After spending a bit of time I was able to make it work. First step was to add the Application ID of the app in Azure as a scope in the Auth. Provider configuration in Salesforce. That removed the No_Oauth_Token error but the authentication to Salesforce still failed. The reason was that Salesforce was attempting to reach our the userinfo-endpoint which wasn’t specified as a userinfo-endpoint is not provided by Azure Active Directory B2C when using a standard policy (a policy is how the authentication flow is configured on the Azure side). As no userinfo-endpoint was provided the solution I came up with was to build a small simple web application that could be a stand-in for that missing endpoint.
The stand-in userinfo endpoint of the web app is called from Salesforce after the user has been authenticated through Azure Active Directory B2C but before the user is let into Salesforce. Salesforce will provide a Bearer token in the Authorization header. The Bearer token is the signed JWT from Azure Active Directory B2C.
The endpoint will do the following:
- Verify the signature of the JWT by getting the key ID (
kid) from the JWT header, then attempt to find the key among the keys loaded from the.wellknownendpoint in Azure when the app started, extract the public key if found and verify the JWT signature - Once the signature has been verified it returns a JSON response with a single claim being the subject identifier (
sub) - The Registration Handler on the Salesforce side can then use this subject identifier to lookup the User record in Salesforce and return it to complete the authentication
The web app is available in a repo on Github (https://github.com/lekkimworld/userinfo-endpoint-for-salesforce-with-azure-ad-b2c). The repo also contains a sample Registration Handler.
YMMV.
Salesforce Privacy Center custom metadata
I was looking for a way to move Privacy Center policies between Salesforce environments so I started looking at custom objects but nothing there really so it couldn’t be data. Next I looked at the installed packages in the org and there were 3 pieces of custom metadata listed. Maybe policies are custom metadata?
Next I created a SalesforceDX project and did a sfdx force:source:retrieve from the Privacy Center org and boy was there a lot of custom metadata records. So my best guess is that the policies are actually custom metadata meaning it could be deployed from org to org with the metadata API. Yay!
The records are split across 3 custom metadata types:
privacycenter_Data_Objectprivacycenter_Data_Fieldprivacycenter_Data_Policy
Salesforce Security Center child tenant user with minimum permissions
In order for Salesforce Security Center to access a child tenant and its data you need to have a user with the correct permissions in each child tenant. Many customers would want the users in the child tenants to have the fewest number of permissions possible. Based on my investigation the user in the child tenant needs to have the following permissions as a minimum:
- API Enabled
- Manage Security Center
- View Roles and Role Hierarchy
- View Setup and Configuration
I have successfully enabled these permissions for a new user by creating a new user in the child tenant using the “Salesforce” license and the “Minimum Access – Salesforce” profile. I then created a permission set with the above mentioned permissions and assigned that permission set to the user I’m going to use to access the child tenant from the parent tenant.
I was then able to authenticate as that user when connecting to the child tenant from the parent tenant.
YMMV!
Language agnostic Salesforce Apex unit test
I was doing some work with packaging on Salesforce and used the dreamhouse-lwc repo as a foundation. When I was building package versions the Apex unit tests were failing as the SOQL queries is using WITH SECURITY_ENFORCED and the user running the queries did not have the right access. The solution was to update the unit test to create a user and assign the dreamhouse Permission Set but to create a user you need to set a Profile. Which one to pick? Easy – use the “Standard User” Profile which is easily accessible by SOQL:
SELECT Id FROM Profile WHERE Name='Standard User' LIMIT 1
This code failed however as the Profile couldn’t be found. It turned out to be because the scratch org created was in Danish so the Profile is called “Standard Bruger” instead. This could be solved by setting the language of the scratch org by using the language key in config/project-scratch-def.json but the repo maintainers didn’t want that. A more flexible and still language agnostic way was to query more intelligently for the Profile. The below SOQL query achieves the same result as above but without setting the org language.
SELECT Name, Id
FROM Profile
WHERE UserType = 'Standard' AND PermissionsPrivacyDataAccess = false AND PermissionsSubmitMacrosAllowed = true AND PermissionsMassInlineEdit = true LIMIT 1
Add language to Salesforce CLI scratch org definition from terminal
All my scratch orgs gets created with the user-language set to Danish which is a good guess but I cannot find anything in Setup that way. No Dev Hub setting I’ve found can change that but setting the language in the scratch org definition file will. That’s easily done from the terminal with jq.
cat config/project-scratch-def.json | jq '. += {"language": "en_US"}' > config/project-scratch-def-en_US.json
Run Apex trigger for Salesforce Platform Event as specified user
By default when you create an Apex trigger in Salesforce to trigger on a Platform Event it will run as the Automated Process system user. This can cause problems when you want to access data or use features that require a “real” user like Chatter. Starting with Spring 21 this has been made a lot better as you can specify the running user and maximum batch size among other things. It’s done through the PlatformEventSubscriberConfig metadata element (or through the Tooling API) and you can read more in the Spring 21 release notes.
The actual configuration is easy enough but I did find one caveat in that it didn’t take effect when deploying a PlatformEventSubscriberConfig record for an existing trigger i.e. a trigger already in the org. The metadata deployed just fine but it didn’t take effect. To fix it I had to delete the trigger from the org and the redeploy the trigger and the PlatformEventSubscriberConfig configuration at the same time.
YMMV.
Note to self – script to update all my CLI stuff
npm_update_all_global() {
npm list -g --json | jq ".dependencies | keys[]" -r | while read line; do
npm -g update "$line"
done
}
brew_update_all() {
brew update && brew upgrade
}
heroku_update_all() {
heroku update
}
sfdx_update_all() {
sfdx update
}
lekkim_update_all_cli() {
npm_update_all_global
brew_update_all
heroku_update_all
sfdx_update_all
}
Video walkthru for the Salesforce Azure client_credentials Auth. Provider
Based on a number of comments I’ve added a video walkthru for the Azure Client Credentials Auth. Provider I have available on Github. The video is hosted on Youtube and besides a description of the elements used shows pushing the source to Salesforce, configuring the Auth. Provider in Salesforce as well as configuring the App Registration on Microsoft Azure.
See the post for the Auth. Provider (Custom Salesforce Auth. Provider for Microsoft Azure client_credentials flow) for a link to Github.