Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to invalidate session cookie, when refresh token expires #1499

Open
skatanski opened this issue Dec 2, 2024 · 6 comments
Open

Comments

@skatanski
Copy link

Version: 7.0.8

.net 8

From documentation, I can see it's possible to synchronize refresh token's lifetime with session cookie in a way that clears refresh tokens when session cookie expires. I can't find, if the other way around is possible - to make it so that session cookie expires, when the refresh token expires. We'd like the user on the front-end side to have to manually re-authenticate, when refresh tokens have expired, with this change being triggered by the back-end.

@skatanski
Copy link
Author

I've investigated it a bit more, and I can see I could implement something like this in the RefreshTokenStore (whenever a refresh token is removed) or in my own implementation of DefaultRefreshTokenService. I could query session store and remove any sessions referenced to a given user/client. But perhaps there's a better way to do it, and if there are any counterpoint/or would it be considered bad practice by adding such functionality in the classes I've mentioned.

@RolandGuijt
Copy link

Setting the CoordinateClientLifetimesWithUserSession option in combination with server side sessions should work. Both the session lifetime and refresh token lifetime should be the same.

The session by default has sliding expiration. Whenever the refresh token is used, then the session is renewed. So if the refresh token isn't used and expires after X hours, then the session will expire at the same time.
The only case where the session would survive past the refresh token is if the user interacts with the IdentityServer but not the client app.

@RolandGuijt
Copy link

@skatanski Did my comment make things clear for you? If so I'd like to close the issue.

@skatanski
Copy link
Author

Hi @RolandGuijt so I've set both:

  • identityServerOptoins.Authentication.CoordinateClientLifetimesWithUserSession to true
  • client specific field CoordinateLifetimeWithUserSession to true

However, after i run following scenario:

  • request access token (lifetime 5 minutes) and single use refresh token (absolute lifetime 10 minutes)
  • new access token/refresh token pair gets requested before 5 minute expiry
  • next time I request new pair - that fails because rightly refresh token got expired
  • I redirect user to login prompt - user gets automatically authenticated with a session cookie

I was expecting that actual login form would show up because the session should have expired along with the refresh token.

@skatanski
Copy link
Author

skatanski commented Dec 16, 2024

Interestingly I've found following issue, which seems to overlap with mine:
#391
However DefaultSessionCoordinationService.ValidateSessionAsync doesn't seem to run, when an authentication using session cookie happens.

@skatanski
Copy link
Author

So I've digged a bit more into it, and my current solution to terminate user session on failed refresh token validation is following:

  • I've derived DefaultRefreshTokenService with my own implementation
  • ValidateRefreshTokenAsync does the following extra, this is a POC:
if (result?.Error == "invalid_grant")
        {
            var refreshToken = await RefreshTokenStore.GetRefreshTokenAsync(tokenHandle);
            if(refreshToken != null)
                await serverSideSessionStore.DeleteSessionsAsync(new SessionFilter { SessionId = refreshToken.SessionId, SubjectId = refreshToken.SubjectId });
        }

This way whenever absolute refresh token expires, session will get terminated as well. I'd need to add client flag to enable it per client.
@RolandGuijt can you please advise if this is the recommended way, or whether I'm missing something/breaking any good practice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants