aspnetcore: MSAL on Blazor WebAssembly fails to initiate sign-in when an invalid_grant or AADSTS700081 error occurs--as in when the refresh token is expired
Describe the bug
MSAL on Blazor WebAssembly fails to initiate sign-in when an invalid_grant or AADSTS700081 error occurs–as in when the refresh token is expired
To Reproduce
My MSAL on the client is configured as:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.Cache.CacheLocation = "localStorage";
options.ProviderOptions.DefaultAccessTokenScopes.Add(
builder.Configuration["AzureAd:MyScopeId"]);
options.UserOptions.RoleClaim = "roles";
});
I sign in to my Blazor Web Assembly app, then wait till my refresh token expires (for me, 1 day). Then I try to refresh the page, which includes a component like this:
<AuthorizeView>
<Authorized>
<span>@context.User.UserId()</span>
</Authorized>
<Authorizing>
Authorizing
</Authorizing>
</AuthorizeView>
Expected behavior
The page should show “Authorizing”, then the code in MSAL that AuthorizeView triggers should automatically initiate a redirect to sign-in, so that the user can go through authentication and thus get a new refresh token and ID token. (Once signed in, the user should redirect back to the same page, which should show the content within the <Authorized> fragment.)
Actual behavior
The page shows “Authorizing”, and the HTTP request POST https://login.microsoftonline.com/0c33cce8-883c-4ba5-b615-34a6e2b8ff38/oauth2/v2.0/token
returns HTTP 400 with
error "invalid_grant"
error_description "AADSTS700081: The refresh token has expired due to maximum lifetime. The token was issued on 2020-11-24T12:56:15.5198672+00:00 and the maximum allowed lifetime for this application is 1.00:00:00.\r\nTrace ID: c4360626-5489-4009-89ad-5ae02bd0ca00\r\nCorrelation ID: 228a7671-3752-4ca9-bf1f-7c0c51368fb6\r\nTimestamp:
Then Blazor allows an exception to be thrown with Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. and further detail. The error is written to the browser console and Blazor shows the standard “An unhandled error has occurred. Reload” bottom banner.`
Possible Solution
Isn’t there some way to configure MSAL to initiate the interactive sign-in process on invalid_grant, rather than having it fail fatally? Or is this just a big bug? Any such action would have to navigate/redirect or popup on the user’s browsing page, not naively redirect an XHR request, of course.
This seems to be similar to: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/2219 , though I am not using MSAL.js directly.
This looks like my situation exactly, but I don’t see how I can mitigate. My code never explicitly calls AcquireTokenSilent.
Additional context/ Logs / Screenshots
Here’s the end of the stack trace: https://gist.github.com/szalapski/942baf9b8da7b5bdb68ebd7f9e2f5544
(Thought I’d post first on MSAL repo, but they say it is a aspnetcore issue.)
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (8 by maintainers)
Great, I got the workaround working. In case anyone else wants to do the same, here is the code:
Part of MainLayout.razor:
CSS:
@szalapski Glad the workaround resolved the issue.
A fix for this will be shipped in 5.0.2.
@szalapski It applies to any scenario where the
GetUserAPI so it shouldn’t affect the error handling you’re using around HTTP requests.Update: I see where the issue is. We don’t have any error handling in the token acquisition in our
getUsermethod which causes exceptions that bubble up from it to be fatal.We didn’t catch this error in our validations/testing because we don’t run into the experienced tokens often based on our test scripts and dev loops.
The fix here is to add some error handling to the
getUsermethod.@captainsafia can you please handle this? Let’s target 5.0.2.