We have two apps - an SPA and a legacy ASP.NET MVC (.NET Framework) app that both use our identity server application (.NET Core 3.1, IdentityServer 4.1) (in production, both apps are behind a gateway and appear to be just different urls on the same host; for local development, I use different ports on localhost for each app). Authentication is working fine - when we log into one app and then navigate to the other, the existing session is recognized and we are authenticated in both apps. So far so good.
However, we're having a strange problem on the SPA if the user logs out of the MVC app from a separate browser window -- Right after the MVC app logout is complete, our SPA's callback gets invoked (presumably by the check session iframe?). Callback then creates a userManager and invokes signinRedirectCallback(), however an exception is thrown from that call, with an error login_required
That seems to then start a loop where callback is called again, fails again and keeps rapidly repeating until the iframe timeout expires.
We use this configuration for userManager:
const settings: UserManagerSettings = {
authority: window.authEndpoint,
automaticSilentRenew: false,
client_id: "js",
post_logout_redirect_uri: window.customUIAbsolutePath,
redirect_uri: `${window.customUIAbsolutePath}/callback`,
response_type: "code",
revokeAccessTokenOnSignout: true,
scope: "openid profile email role api1 IdentityServerApi",
};
And on our identity server, the client is configured as
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Code,
RequireClientSecret = false,
RequirePkce = true,
RedirectUris =
{
$"{customUIBaseUrl}/callback",
},
PostLogoutRedirectUris = { omniusUIBaseUrl, customUIBaseUrl },
AllowedCorsOrigins = { customUIDomain },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
JwtClaimTypes.Role,
IdentityServerConstants.LocalApi.ScopeName,
"api1",
"api2"
},
UpdateAccessTokenClaimsOnRefresh = true
},
So, is this a bug in oidc-client or maybe a configuration error somewhere? If not, what is the correct way to handle the login_required failure response from signinRedirectCallback()?
That error means that the request to the authorization endpoint via the iframe is not authenticated. The cookie is gone, invalid, expired, or simply not sent due to cross-site calls.
@brockallen Thanks for the explanation - it makes sense, as the user is really logged out at that point.
But if I don't do "something" to handle the error condition, I just end up in that rapid-fire loop until the iframe times out. Can you suggest an appropriate action in response to that error?
Handle the userSignedOut event and do your cleanup there?
I'll give that a try. So I just let the iframe window timeout and ignore the errors?
Have same error too. Wonder how to handle it gracefully.
Listen for userSignedOut event works for me.
Most helpful comment
I'll give that a try. So I just let the iframe window timeout and ignore the errors?