Identity Provider Story
Basic assumptions:
- in-browser authentication,
- with OAuth2/OpenID Connect (but also applicable for SAML),
- for Web, SPA and Mobile applications.
Let’s start with a story: The user enters the address ‘https://portal.my-company.com’ to check company news; without an active session in the application (cookie or token), the application will be redirected to the Identity Provider (IdP) - authentication is required. After the identity verification and authorization, an IdP session will be created and the user redirected to the application.
With the same browser, the user tries to access the following application: ‘https://crm.my-company.com’. With the same schema, the user will be redirected to the IdP, but now, based on the active session (SSO), the user will be automatically redirected to the application.
Side note: Remember about delete and block account operations designing SSO and token refresh operation.
We focus here on the Entra ID (and Entra External ID), but the same applies to other providers like Azure AD B2C or Auth0 - the OpenID Connect standard covers a big part of the article.
Cookies
With Entra ID (IAM), SSO is less complicated than Entra External ID or Azure AD B2C (CIAM). The additional complexity in the CIAMs is the possibility of using more than one domain for IdP. A friendly reminder:
- 💥 Cookies are assigned to the domain and enable the SSO for our applications.
- 💥 Cookies are stored inside the Browser, so when we sign in with Incognito mode or with different browsers, SSO doesn’t work ⚠️.
- 💥 ‘Keep Me Signed In’ stores a persistent cookie. It improves user experience when you close and reopen browser sessions without signing in.
To check what cookies are stored in the browser, we can use the Developer Tools (F12) and check the Application tab; we can be based on the MS Documentation Entra ID cookies.
Force the user to provide credentials
When the user should be forced to provide the credentials, extend the request to the authorization endpoint with an extra parameter. With Azure AD B2C and Custom Policy framework, the customization is even more extendable. We can disable SSO for dedicated policies.
Here is an example of how to use prompt=login
param:
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
&prompt=login
The best place to check the authorization endpoint query parameters is the Entra ID OpenID page.
Step-Up authentication
Step-Up is a part of the standard for Identity Provider (Check RFC
We can force the user to provide additional credentials. In the Entra ID environment, with the token claim acrs
we can review/access the authentication context. A typical case for step-up authentication is when we want to access sensitive data or execute a high-risk operation. We can force the user to authenticate with MFA or from a specific location. In addition, we should remember that there is a dedicated framework, Conditional Access Policies, but this is a topic for another article.
Entra External ID
We need to configure the Conditional Access policy and return acrs
claim in the token.
To force Entra External ID to ask the user for additional credentials, we need to add a query parameter with URL-encoded JSON. We base on the policy to force MFA:
{"access_token":{"acrs":{"essential":true,"value":"c1"}}}
Federation
A federation is a concept of trust. Based on the example of Google or Apple ID - we trust and accept the identity of the user from the external Identity Provider (IdP) in our solution, Entra External Id. We trust that external IdP:
- Provide the expected security level for the account (MFA, password complexity, etc.).
- It is compliant with the system regulations and expectations (GDPR, etc.).
⚠️Important The federation will be configured and maintained on the Google or Apple ID side. In the context of OAuth2, the
redirect URI
and theclient_id
withsecret
will be generated and should be maintained.
💡Side note: With Verifiable Credentials, the situation is different. With the presentation of the credentials, the requesting system is responsible for the ’limitation’ and ’trust’ of the presented credentials (allowed issuers) - there is no need for the configuration on the issuer side.
Entra ID Guest User
For collaboration across Entra ID tenants, we can use the Guest User feature. With a simple step, we can invite the user from a different tenant.
✏️Note
Guest User
can be used to enable the SSO for the Entra ID workforce in the Entra External ID (CIAM) tenant. The invitation can be created in the Azure Portal or via the Graph API.
Block the account
What if we decide to block or remove the account?
- We should consider to sign-out the user from the application and the Identity Provider (to remove the session and cookies).
- When we use access and ID tokens, they should be short-lived, and the refresh token should be revoked.
- IdP session should be invalidated.
- MSAL library will help us on the application level.
With a block of the code (pseudo-JavaScript) based on the MSAL library, we force the user to redirect to the login page.
const tokenRequest = {
account: accounts[0],
...loginRequest,
forceRefresh: true // Force MSAL to get a new token from the server
};
try {
const response = await instance.acquireTokenSilent(tokenRequest);
toast.success('Token refreshed successfully!', {
duration: 3000
});
} catch (e) {
if (e instanceof InteractionRequiredAuthError) {
try {
await instance.acquireTokenRedirect(tokenRequest);
} catch (redirectError) {
const errorMessage = `Failed to refresh token: ${redirectError.message}`;
setError(errorMessage);
toast.error(errorMessage);
}
}
}
As a result, the user will get the following:
Typical issues and considerations
- With CIAM solutions, we use different domains for the IdP. With cookie(s) for the domain, we can’t use SSO for different domains. We should keep the same domain for the IDP and applications.
- Calculate the risk and security level; based on the calculation; enable the expected lifetime of the session, token, and refresh token.
- ‘Keep Me Signed In’ - By selecting this option, to improve the user experience for SSO.
- In the case of Entra External ID Native Authentication - SSO is not supported - native authentication is required in application implementation, so SSO is impossible.
- The Sign-In behavior on the devices is different. On the iOS, there is a prompt to open the browser, but for Android not.
- Persistent cookies will be handled by the browser. The behavior will be different for Firefox and Chrome.
Links
- https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc#send-the-sign-in-request
- https://learn.microsoft.com/en-us/entra/identity-platform/developer-guide-conditional-access-authentication-context
- https://github.com/AzureAD/microsoft-authentication-library-for-js
- https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-web-browser-cookies