App Service and OpenID Connect with Salesforce
Posted on: March 25, 2024Azure App Service is one of those services that has a lot of features and capabilities. It’s the go-to service for hosting web applications, REST APIs, and mobile backends.
One of the built-in features is authentication. It’s often referred to by the name Easy Auth. It supports many identity providers including any OpenID Connect capable identity provider.
In this post, I’ll show how to configure your App Service to use Salesforce as the identity provider. Read more from the documentation about how to configure your App Service or Azure Functions app to sign in using an OpenID Connect provider.
Here’s a high-level overview of App Service authentication process:
as a anonymous user EasyAuth->>User: Redirect to
authentication provider User->>AuthProvider: Login AuthProvider->>User: Redirect back to web app User->>EasyAuth: Access web app
as a authenticated user Note right of EasyAuth: Add identity
to HTTP headers EasyAuth->>AppService: Request Note right of AppService: Access
headers AppService->>User: Response
Easy Auth is especially handy if you don’t want to use any custom code to handle the authentication or have older application that you just want to publish to you end users and quickly enable e.g. Entra ID authentication.
You can start the configuration process by navigating to your App Service and then selecting Authentication from the left-hand side menu:
You can then select Add identity provider and then OpenID Connect:
It will then ask you to provide the Document URL, Client ID and Client Secret for your OpenID Connect provider:
Since I’m using Salesforce as my OpenID Connect provider, I can follow the official documentation on how to create a Connected App which then allows me to use it as identity provider.
I navigated to my developer instance:
I followed the documentation and created a new Connected App called Azure App Service. These are the most important settings that I configured:
- Callback URL to match my App Service URL:
https://....azurewebsites.net/.auth/login/SalesForce/callback
- Required OAuth scopes:
openid
profile
email
Here’s my configuration:
I copied also Consumer Key and Consumer Secret:
I took a note of the Document URL based on the documentation:
https://jannemattila....develop.lightning.force.com/.well-known/openid-configuration
Your Document URL should respond anonymously with the OpenID Connect configuration.
After that, I went back to my App Service and filled in the required fields:
- Open ID provider name: SalesForce
- Document URL: https://jannemattila….develop.lightning.force.com/.well-known/openid-configuration
- Client ID: Consumer Key
- Client Secret: Consumer Secret
After saving the above configuration, I just opened that app service url and I got redirected to Salesforce login page. After successful login, I got a consent screen and then I was redirected back to my web app:
My app echoes HTTP headers and you can see that identity headers are also included:
I can further analyze that token in jwt.ms:
{
"sub": "https://login.salesforce.com/id/00...3IAK",
"zoneinfo": "Europe/Helsinki",
"email_verified": true,
"address": {
"country": "FI"
},
"profile": "https://jannemattila....develop.my.salesforce.com/00...3IAK",
"iss": "https://jannemattila....develop.my.salesforce.com",
"preferred_username": "janne@jannemattila.com.sandbox",
"given_name": "Janne",
"locale": "fi_FI_EURO",
"nonce": "30c859e4d3db4cd582d90fe1f99b412d_20240312183519",
"picture": "https://jannemattila....develop.file.force.com/profilephoto/005/F",
"aud": "3MVG9k02hQh...DMAq__V3nZyvAhh",
"updated_at": "2024-03-12T17:15:44Z",
"nickname": "User17102629103167723373",
"name": "Janne Mattila",
"phone_number": null,
"exp": 1710271821,
"iat": 1710268221,
"family_name": "Mattila",
"email": "janne@contoso.com"
}
Of course, I did stumble a bit while configurating Connected app in Salesforce side, but Diagnose and solve problems feature in App Service helped me to understand what was wrong in my configuration:
Easy Auth Errors/Warnings:
I had unnecessary configuration related to the audience and that was causing the problem because token validation failed.
I hope you find this useful!