Thumbnail SharePoint Framework (SPFx), Authenticating to Api’s and Third Party Cookies

SharePoint Framework (SPFx), Authenticating to Api’s and Third Party Cookies

Important: Microsoft has promised to deploy changes in January/Februari 2024, containing an update that fixes the behavior described in this blog post. On page-load, a refresh token will now be retrieved through a full-page redirect, whether webparts call Entra ID-secured endpoints or not. This is good news, even if it's slightly worse in terms of user experience. More information

Maybe you’ve experienced it: you’ve built a nice SPFx webpart, but some users complain about SharePoint pages loading twice, triggering a refresh just after the page has rendered. Or about SharePoint pages reloading at random intervals. And those pages happen to contain your webpart. Odds are, those users are on MacBooks, browsing SharePoint with the Safari browser. Or they are using the Mozilla Firefox browser. So what’s going on there? It might just be related to Authentication and Third Party Cookie blocking.

It’s a well-known and often implemented scenario: a set of SPFx webparts that shows data loaded from an Api secured by Entra ID; an Azure Function App for example, or an App Service. Microsoft has made it quite easy to implement this on the SPFx side. You just use the aadHttpClientFactory and the authentication part is taken care of for you. It just works.

Unless you’re on a browser that has blocked Third Party Cookies. Third party cookies are cookies that are sent on requests to domains other than the domain showing in the address bar of the browser. These are a privacy concern because they make it possible to track users across the internet. Many browsers have started or planned blocking them. Safari on MacBook already has the Intelligent Tracking Protection feature on by default. Mozilla Firefox also disables these cookies by default. Google Chrome has planned disabling them by 2023. On Microsoft Edge these cookies are currently not blocked by default.

Blocking third party cookies in Microsoft Edge

Privacy is good, but as Apple writes in their description of ITP, there are unintended consequences, like breaking ‘Single sign-on to multiple websites controlled by the same organization’. And that is exactly what is happening when browsing pages that contain SharePoint Framework webparts connecting to other Api’s. Currently (on SPFx version 1.12.1), the Microsoft Authentication Library v1.4 (MSAL.js) is used to authenticate to Api’s. The authentication mechanism in MSAL.js v1 is an implementation of the OAuth Implicit Grant Flow. The implicit grant flow, among other things, means that an invisible iframe will be used to send hidden sign-in requests. That iframe is pointed at the Microsoft login endpoint (login.microsoftonline.com) and the idea is that the Microsoft Identity cookies are sent along with that call, so that the endpoint knows who you are. But this doesn’t happen when Third Party Cookies are blocked. After all, the URL in the address bar (https://<tenant>.sharepoint.com) is different from the URL requested in the iframe (https://login.microsoftonline.com). So SharePoint Framework cannot successfully acquire a token because login.microsoftonline.com does not know who is calling it and if that person is signed in. It instead throws back the following error:

InteractionRequiredAuthError: AADSTS50058: 
A silent sign-in request was sent but no user is signed in. 
The cookies used to represent the user’s session were not sent in the request to Entra ID. 

It’s basically ‘knock knock, who’s there?’ With no answer following the question.

Fortunately, Microsoft has implemented a fallback scenario. If a token cannot be successfully acquired, SPFx will redirect the users entire browser tab to the following url: https://<tenant>.sharepoint.com/_forms/spfxsinglesignon.aspx. This request will be forwarded on to login.microsoftonline.com and back again to the page the user was on. The following picture shows the activity in the DevTools Console. The ‘Preserve log’-option is enabled to see the follow up across redirects:

The redirect as logged in DevTools

So even though the Microsoft login endpoint threw an error the first time around, the token is still acquired successfully during this second call, because login.microsoftonline.com was now accessed directly on the browser address bar. The authentication was successful, the token is cached and the user can now load data from the Api. But it comes with a price: the user is redirected, he sees the entire page flashing and reloading.

And what’s more, with the OAuth Implicit Grant flow this might happen multiple times. Every time SPFx tries to refresh an expired token, it tries the hidden iframe. Entra ID access tokens generally expire after an hour. So when a user stops interacting with the browser and after one hour clicks on a button that executes a request to the server, the same thing happens again. And in such a scenario the user might even have to click the button twice, as POST requests are not retried after the redirect to spfxsinglesignon.aspx.

Part of this problem will be fixed when the SharePoint Framework will switch to using MSAL.js version 2. This will probably be done by Microsoft sometime soon. But you can already try this out if you want. It has been demonstrated by Markus Moeller how this can be implemented.

MSAL.js v2 no longer employs the Implicit Grant Flow, but uses the PKCE Authorization Code Flow, which is more secure, and has the added benefit of issuing Refresh Tokens. The Authorization Code Flow does not return an access token, but an authorization code which needs to be redeemed. (The plumbing is all taken care of for you by MSAL.js) After the authorization code has been redeemed, you can continue requesting new access tokens as long as 24 hours into the future. So no more redirects…

Unfortunately that isn’t entirely true. Because of the existence of a refresh token, refreshing the token will indeed no longer trigger a redirect within the 24 hour window. But the first time SPFx would request a token, it still would need to use a redirect page like spfxsinglesignon.aspx to get the access and refresh tokens in the first place. This doesn’t change with the move to the Authorization Code Flow. There is a balance to be struck here between User Experience and Security/Privacy. And in this case, the impact is with UX. So when all browsers have blocked Third Party Cookies we’ll probably be seeing a lot more redirects and complaints from users. Unless Microsoft has thought of some solution to circumvent this.

Instead of redirecting the user, MSAL.js v2 also supports authentication using popups. This is probably a less intrusive way of getting an access token. But for SPFx it’s not an optimal form of User Experience all the same. It often needs explicit user interaction, (ie: a user clicking a button) otherwise the browser blocks the popup. Neither does it seem futureproof, as browsers have been limiting/decreasing support for popups for a long time.

Another solution is waiting for Microsoft to at least solve this in Edge. Maybe the Microsoft Edge team will implement a Third Party Cookie exemption for Microsoft tools accessing login.microsoftonline.com. If you are less prone to waiting on that, you might try to convince the IT department to allow Third Party cookies on sharepoint.com for managed devices:

Setting Third Party Cookie exception for SharePoint

That doesn’t solve the issue for unmanaged Apple Devices with ITP enabled though. Or for other browsers for that matter. Plus it opens up the possibility of actual tracking cookies being used on SharePoint.

However this is going to play out in the near future, developers will need to think carefully when using Api’s secured by Entra ID. Requesting access tokens for multiple resources on the same page might just lead to a redirectocalypse. Aside from that it is also important just when the token is requested. You can imagine access tokens that are only required when the user performs a certain action on the page, for example clicking a button. But most of the time it would probably be wiser to acquire it immediately at pageload. This because the user is already waiting for the page to be rendered.

Note: If anyone knows more about the probable future, or has some corrections on my description of the present, I'd like to be corrected, please drop me a post using the contact form.

spfx authentication entraid
Support me by sharing this

More

More blogs

SharePoint Framework, Docker, Dev Containers and NPM linking
SharePoint Framework, Docker, Dev Containers and NPM linking

When using SPFx Library Components we are instructed to execute npm link when debugging our webparts. But what if we are using dev containers?

Read more
Resource Specific Consent - Using delegated Sites.Selected
Resource Specific Consent - Using delegated Sites.Selected

Sites.Selected has been made available in delegated mode! What does it mean and how does it work?

Read more
Deploying SPFx apps with Azure DevOps pipelines - all YAML variant
Deploying SPFx apps with Azure DevOps pipelines - all YAML variant

In this blog post I will show you how you can deploy SPFx apps using Azure DevOps pipelines with an all YAML build & release definition.

Read more

Thanks

Thanks for reading

Thanks for reading my blog, I hope you got what you came for. Blogs of others have been super important during my work. This site is me returning the favor. If you read anything you do not understand because I failed to clarify it enough, please drop me a post using my socials or the contact form.


Warm regards,
Martin

Microsoft MVP | Microsoft 365 Architect

Microsoft MVP horizontal