IdentityModel / IdentityModel.AspNetCore

ASP.NET Core helper library for claims-based identity, OAuth 2.0 and OpenID Connect.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Distributed session management over refresh token and session id

PascalSenn opened this issue · comments

I am coming over from https://github.com/DuendeSoftware/IdentityServer/discussions/196

Current Situation
Until a few weeks ago we were using access token to authenticate users. We challenged in the frontend and authorized the calls to our backend with a token. Then we started to look into https://github.com/DuendeSoftware/BFF to use cookie authentication and keep the client access token free. Our backend services are hosted in a Kubernetes clusters with N instances per service.
A request from the frontend to the backend is load balanced and can hit one of the instances in the backend. This means we cannot use server-side sessions and must include the access token in the cookie.

What could be improved
We do not want to use sticky sessions because this implies state on the server and brings a whole new set of challenges. When the access tokens are included in the cookie, the cookies are chunked because of the size of the access tokens. The cookies also increase the request payload as the access tokens have to be attached to each request.
In an ideal world, we would just want to set the session id in the cookie and therefore have a slim, non-chunked cookie.

What may be a solution
Instead of including the session id and the access token in the cookie, we could include the session id and the refresh token in the cookie. This would reduce the size of the cookie and avoid cookie splitting.
The flow would look something like this:

1. Initial Request
image
The user is not authenticated and has no cookie. On the first request to the BFF the user is challenged on the IDP.
On successfull authentication the BFF creates a session and stores the access token. It also sets a cookie on the response with the session id and the refresh token.

2. Request on a different instance
image
The user was authenticated on BFF{1}, has a cookie and a session exists. The next request hits BFF{2}. The server knows that the user is authenticated and has a session but does not have an access token. It requests an access token on the IDP with a refresh token, creates a session and stores the access token. On the response a cookie is set with the new refresh token.

3. Normal request
image
The user now has a cookie with the session id. There also exists a session with this id on each instance of the BFF. The user can send a request to any of the instances and has a access token to pass along to downstream services.

OK - I think this is possible without any fundamental changes. You would hook into the OIDC handler to not store the access token in the session (probably the OnCreatingTicket event) - and use the IUserAccessTokenStore to amend a in-memory access token based on the stored refresh token.

Have you tried that?

any update?

Did you ever try my suggestion?

@leastprivilege This is what we ended up with: DuendeSoftware/BFF#31 :)
There are a few limitations in the implementation because IDistributedCache works as a key value store.
If you guys are interested in the feature we can work out on the PR what is needed to get the PR merged.
Going to close this Issue to not clutter your issue board :)

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue.