The bearer token for Graph doesn't get updated properly and will not refresh once expired, causing all calls done via the MSGraphClient to fail.
We have a single app page running on SPFx 1.10 which does occasional calls to graph endpoints using the MSGraphClient. Starting last week Wednesday these calls fail intermittently after 1 hour (when machine goes into sleep mode, network is offline, etc). We can see that the token does not get refreshed, but the expiration value DOES change when it attempts to get a new token. Removing both values from the SessionStorage helps most of the time, the GraphClient will then get a new token and things work again (very rarely we will get the old token again, which is expired???).
I've created a small sample webpart which does a call to /me every 5 minutes and prints results for the call & token values. Here we see the value for the expiration increase every call, obviously the token itself stays the same. It won't update the token and when it expires we see the call starting to fail.
Upgrading to 1.11 doesn't seem to fix the bug, and due to QA requirements we'd like to keep to 1.10 if at all possible.
Run a graph call on the page once every N time and wait for the token to expire. If this fails, see how you won't get another token unless you remove the value from the SessionStorage. You may need to disable network, or put the machine in sleepmode for easier reproduction. It doesn't happen consistently, if you have the browser open in the background it tends to work ok most of the time.
I expect the token to properly refresh once it expired.
I can provide a sample project, and if wanted we can demo this within our product.
Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.
MSFT is in the midst of rolling out a fix related to obtaining a token (#4892)... not sure if it's related to this. @lahuey, do you know if this is part of that fix?
We have the similar issue with AadTokenProvider. As soon as token is expired it is not being renewed and app is stuck until session storage is cleared (thanks for the tip)
We are having the exact same issue with AadHttpClient in our SPFx web parts that consume Azure AD-Secured APIs. The first time user accesses a page with an SPFx web part that consumes an Azure AD-Secured API it works fine. But after a period of inactivity like 30 mins, if the user tries to access the same page or another page with another SPFx web part that makes an Azure AD-Secured API call the request fails with a 401 unauthorized error. Based on our troubleshooting, the AadHttpClient is still using an expired access token from a previous session. The older access token gets cached and there is no way to get out of this. Closing the browser or clearing browser cache doesn't resolve this issue. This is the same behavior in new Edge and Chrome.
SharePoint Online REST APIs are working fine. We have a few pages that have multiple web parts and the web parts consuming SPO APIs are working fine but the ones consuming Azure AD-Secured APIs are failing.
We are currently experiencing production outages due to this issue. A critical case was opened with Microsoft yesterday but seems like we are having very hard time trying to get to the product team. This is absolutely frustrating as our hands are totally tied and we are not getting much help from Microsoft.
Are there any updates on this issue?
We're also seeing this exact issue on our solutions. Refresh token isn't refreshed properly. Kill & re-open the tab (so the session storage is cleared) and it comes back to life.
We've been working with support for a while on this issue, and it should have landed at the Product Group now. No solution in sight as of yet though :(
I have found that the issue is that the expiration value in the browser session cache is out of sink with the expiration on the token itself. So the token in the session cache is expired, but the expiration value shows it is still valid. This is under review from the product group.
Any news about this Bug ? I have the same error the MSGraphClient token not refreshed properly,
We are also experiencing this problem in an application. The application relies on the aadHttpClient to retrieve information from a back-end API, and calls stop working after one hour.
By inspecting the session storage at the expiration time, we can see that the expiration time (key "...|adal.expiration.key|...") is updated, but the JWT token (key "...|adal.access.token.key|...") is not. By inspecting the HTTP traffic with Fiddler, I could not find a connection to login.microsoftonline.com, so I suppose no new token was retrieved.
Checking with SP engineering... not sure if this is a bug (ie: SPFx API should automatically fetch a new access token after expiry) or by design (ie: something the developer would have to manage). Once I know something I'll follow up...
@andrewconnell I don't think the token provider used by MSGraphClient is even publically available via the API... (I could be wrong)
@jimmywim Pretty sure it is... this isn't a complete sample, but you get the picture. None of those APIs or methods are marked as internal in the type declarations which = public.
this.context.aadTokenProviderFactory.getTokenProvider().then((p) => {p.getToken})
Ah, and is the TP returned by that factory the same as is used in MSGraphClient? i.e. preconfigured with the Client ID of the app registration in Azure, etc.? If so you may be onto something (but we'll wait til engineering say what's the way forward).
The only thing the current one does is (1) use the AadHttpClient to obtain an access token (because MSGraph is an Azure AD secured resource) & (2) initialize the MS Graph JS SDK.
IOW, the MSGraphClient in the SPFx API is just a thin helper wrapper to existing APIs. That's why the original Graph client was deprecated & retired... it was a full SDK built by the SP team to talk to the Graph REST API, which makes no sense for them to maintain after the Graph team released a JS SDK.
Got it - makes sense now, thanks - also now understand why token refresh may be something that we need to look after if the TP isn't doing it automagically for us.
That's the part I'm not sure about... is it intended for the SPFx API to do this for you, or not. I can see both sides... that's why I'm checking with engineering if this is by design or if something isn't working.
Same issue here in production solutions that are calling AAD protected API endpoints... never noticed this issue before though, while I'm using the AadHttpClient a lot. Not sure how this one sneaked in.
Spoke to SP engineering... here's the gist of it:
They are aware of this and a few other identity things. You may have noticed that MSFT recently announced they were dropping support for ADAL.JS which is what the SPFx API leverages for token ACK.
They are working to update their identity libraries to MSAL.js(IMHO, the right call) which they believe will resolve some of these known issues... including the one in this issue (as well as others... for example, some have creeped up due to recent changes in Chrome & Safari).
Before you ask... do I have an ETA? Nope... they are working on it. My $0.02: I imagine there are complexities (it is identity stuff) so it's more important this is done right than fast.
So... I guess all I can say: stay tuned... :-/
The new implementation has been deployed to one of our tenants and indeed solved the problem. We are now waiting for the other 2 tenants to be updated too.
@lucmoco can you please provide more details on new implementation. We are also facing this issue in our prod site and we need to resolve it on ASAP basis. It would be great if you could provide the changes we need to make our tenant work as well.
@andrewconnell any idea what @lucmoco is referring to?
@jkondakindi prob this https://github.com/SharePoint/sp-dev-docs/issues/4892#issuecomment-663165736
@ghost = GH's user that represents a deleted user. No idea why the MSFT engineer deleted his account, but that was from Landis on the MSFT SP engineering team.
4892 was a separate issue than the current issue with the expiration tokens. The new MSAL work should resolve several remaining issues.
@asim-bashir-confiz , @jkondakindi, the fix comes from Microsoft, and is likely being installed on tenants progressively. I could see that by inspecting the session storage. In Chrome, open developer tools (F12), and in the "Application" tab, have a look at the session storage for the SharePoint site. SPFx saves access tokens there.
With the old version, you can see two keys, similar to this:
{AAD user GUID}|{SPFx app principal GUID}|adal.access.token.key|{target app GUID or MS Graph URL}
{AAD user GUID}|{SPFx app principal GUID}|adal.expiration.key|{target app GUID or MS Graph URL}
The first key contains the access token, valid for 1 hour. The second key contains the expiration time as stored by the SPFx JavaScript. The bug is that when the token must be renewed, the expiration time is updated, but not the token, and thus calls to APIs fail.
With the new version, there is only one session storage key, similar to this (I've pretty-formatted it):
{
"authority": "https://login.microsoftonline.com/{Tenant GUID}/",
"clientId": "SPFx app principal GUID",
"scopes": "{target app GUID or MS Graph URL}/user_impersonation {target app GUID or MS Graph URL}/.default",
"homeAccountIdentifier": "{base-64 encoded AAD user GUID and Tenant GUID}"
}
The value is a JSON object containing both the access token and the expiration time. That new version fixed the authentication problem for me. The fact that now scopes are being saved instead of the target app GUID alone suggests that this is the new implementation based on MSAL.js that @andrewconnell mentioned.
Of course this all is pure reverse engineering and subject to change anytime !
This fix is part of the JavaScript services provided by the SharePoint page, and managed only by Microsoft. It is not part of the SPFx framework, so there is no change in code or npm packages update we can do to enable it. We just have to wait !
Any updates on this? Has anybody received the Microsoft fix yet?
We reported the issue to Microsoft support but it has been quiet the last couple of days.
At least we haven't. We are using single app part page with SPFX and facing the token expiry issue. The token expires after X amount of minutes and then we have to close the browser to get refreshed token.
@MRuimerman @asim-bashir-confiz, see https://github.com/SharePoint/sp-dev-docs/issues/6135#issuecomment-682271947 & https://github.com/SharePoint/sp-dev-docs/issues/6135#issuecomment-681975610 above for more detail
@andrewconnell: Thanks. where can we find details about new MSAL work and how can we implement in our project?
It's 100% internal to SPFx and you won't have to do anything. Just use the SPFx API. IOW, there's nothing to share beyond what's in the referenced links above.
@andrewconnell thanks. I get your point. Which version of SPFX will have this fix?
@asim-bashir-confiz ¯_(ツ)_/¯ I've shared all information I have on this topic.
Following...
I too bumped into this issue today...
We have been experiencing the same problem for about two weeks now.
has anybody found any quick-fix or workaround for this issue?
I did find this blog that uses MSAL 2.0 to get a token and then sends it via the graph client. You can add headers to the request to add in the bearer token-
https://mmsharepoint.wordpress.com/2020/08/15/using-msal-js-2-0-in-sharepoint-framework-spfx/
This has been an issue we have noticed for the last 2 weeks.
Really interested in getting this fixed as it is impacting the webparts we have built.
The new MSAL-based SPFx authentication that had been deployed by Microsoft to one of our tenants and had fixed the problem for us has been reverted back to the old version. I guess the new implementation is not deemed stable enough...
The MSAL implementation works in my case when i use a SPFx webpart in browser. I am not sure how to deal in case of a SPFx webpart being used as teams tab.
Any updates regarding this bug?
The rollout of the new MSAL auth did have a problem and they are working to resolve the issues and have a current rough ETA of the first week of October.
@westleyMS Did this roll out as expected, do you know?
There was a delay to fix a regression the fix caused in another component, the other component was fixed and is being rolled out. Then they will roll out the fix again. I don't have an ETA on that.
It rolled out to our customers tenants today, saw some changes in the sessionStorage variable as well. Seems better to me right now, 1 sessionStorage key with all the required information (accessToken, expireDate, ...) in one object.
I can confirm that the new version has been deployed to our 3 tenants.
We've also seen the issue fixed, so I think we can close this ticket :)
The new version is not installed to any of our tenants anymore. It looks the old version has been restored again.
Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues
Most helpful comment
@asim-bashir-confiz , @jkondakindi, the fix comes from Microsoft, and is likely being installed on tenants progressively. I could see that by inspecting the session storage. In Chrome, open developer tools (F12), and in the "Application" tab, have a look at the session storage for the SharePoint site. SPFx saves access tokens there.
With the old version, you can see two keys, similar to this:
The first key contains the access token, valid for 1 hour. The second key contains the expiration time as stored by the SPFx JavaScript. The bug is that when the token must be renewed, the expiration time is updated, but not the token, and thus calls to APIs fail.
With the new version, there is only one session storage key, similar to this (I've pretty-formatted it):
The value is a JSON object containing both the access token and the expiration time. That new version fixed the authentication problem for me. The fact that now scopes are being saved instead of the target app GUID alone suggests that this is the new implementation based on MSAL.js that @andrewconnell mentioned.
Of course this all is pure reverse engineering and subject to change anytime !
This fix is part of the JavaScript services provided by the SharePoint page, and managed only by Microsoft. It is not part of the SPFx framework, so there is no change in code or npm packages update we can do to enable it. We just have to wait !