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

openid session storage should be deleted when the authcode is exchanged #790

Closed
3 of 5 tasks
cfryanr opened this issue Feb 2, 2024 · 9 comments · Fixed by #793
Closed
3 of 5 tasks

openid session storage should be deleted when the authcode is exchanged #790

cfryanr opened this issue Feb 2, 2024 · 9 comments · Fixed by #793
Labels
bug Something is not working.

Comments

@cfryanr
Copy link
Contributor

cfryanr commented Feb 2, 2024

Preflight checklist

Ory Network Project

No response

Describe the bug

I work on a project that use fosite as a golang package and implements the fosite storage interfaces in a custom way. The DeleteOpenIDConnectSession interface has never been called and more recently has been marked deprecated. However, this is a problem for the fosite storage interfaces.

The storage interfaces are very nicely designed and gives implementors lots of flexibility in how the underlying storage works. In our project, for several technical reasons (including that we are not using SQL), each storage interface gets stored in the underlying datastore separately, with no connection to each other. Because the openid sessions are never deleted, we have no choice but to allow them to linger for longer than is actually necessary, using up storage in the underlying datastore.

If I understand the code correctly, there is no reason to keep the openid session data after the authcode is successfully exchanged in PopulateTokenEndpointResponse of flow_explicit_token.go, so that function could call DeleteOpenIDConnectSession before it returns.

I understand that other implementations of the storage interface might choose to store the openid session data along with the authcode session data (e.g. together in a SQL table), and therefore incur less overhead in the underlying datastore. It's nice that the fosite storage interface gives that flexibility. However, the storage interfaces should not require or assume that style of implementation, and none of the other fosite storage interfaces require it except for the openid interface.

Might you consider accepting a PR which removes the deprecation notice on DeleteOpenIDConnectSession and adds a call to that function in the appropriate place? Storage interfaces which do not need it could simply implement it as an empty (no-op) function, which they are most likely already doing anyways.

Reproducing the bug

In the source code, you can see that the DeleteOpenIDConnectSession is never called, and is marked deprecated.

Relevant log output

No response

Relevant configuration

No response

Version

v0.44.0

On which operating system are you observing this issue?

None

In which environment are you deploying?

None

Additional Context

No response

@cfryanr cfryanr added the bug Something is not working. label Feb 2, 2024
@cfryanr
Copy link
Contributor Author

cfryanr commented Feb 12, 2024

According to the comments on #538 (comment) it was decided to deprecate the DeleteOpenIDConnectSession function because:

Not sure if it makes sense to delete the rows though as it contains info required for refreshing the oidc session

Note that discussion about "rows" is specific to how Hydra chooses to implement the storage interface.

In general, the above is not a true statement about how the fosite storage interfaces work. Note that GetOpenIDConnectSession is only ever called by PopulateTokenEndpointResponse in handler/openid/flow_explicit_token.go. Also note that the PopulateTokenEndpointResponse function only works for authorization code exchanges because the first line of the function returns an error unless the grant type is authorization_code. Therefore, the openid session storage is only ever needed during authorization code exchange, and has no impact on refresh grants.

If Hydra's storage implementation does not want to delete openid session storage during authorization code exchange, it could choose to make its implementation of DeleteOpenIDConnectSession a no-op, rather than deprecating DeleteOpenIDConnectSession.

aeneasr pushed a commit that referenced this issue Feb 13, 2024
…nge (#793)

Remove deprecation of `DeleteOpenIDConnectSession` storage interface function and call it during
authorization code exchange. This function was not previously called. Implementors of the openid
storage interface who which to preserve the old behavior should implement this function as a
no-op which returns `nil`.

Fixes #790
james-d-elliott pushed a commit to james-d-elliott/fosite that referenced this issue Feb 15, 2024
…nge (ory#793)

Remove deprecation of `DeleteOpenIDConnectSession` storage interface function and call it during
authorization code exchange. This function was not previously called. Implementors of the openid
storage interface who which to preserve the old behavior should implement this function as a
no-op which returns `nil`.

Fixes ory#790
@mitar
Copy link
Contributor

mitar commented Mar 7, 2024

What about DeleteAccessTokenSession? That also seems it is never called?

See also #798.

@cfryanr
Copy link
Contributor Author

cfryanr commented Mar 7, 2024

@mitar, fosite will call RevokeAccessToken from the TokenRevocationStorage interface instead of calling DeleteAccessTokenSession. I'm not sure of the history or reason behind that, but it has been that way for years.

@mitar
Copy link
Contributor

mitar commented Mar 7, 2024

But that is done only in memory storage implementation. This is not done necessary in all storage implementations?

@cfryanr
Copy link
Contributor Author

cfryanr commented Mar 7, 2024

For example, RevokeAccessToken is called by the token endpoint in several cases where the access token should be revoked based upon client actions. It is up to the implementor of the storage interface to cause that function to delete the access token session from storage.

However, I think you are correct that when the access token has expired, nothing in fosite will call the storage interface to tell it that the token has expired. It seems to be up to the implementor of the storage interface to handle garbage collecting old expired sessions without any help from fosite, if I understand correctly.

@mitar
Copy link
Contributor

mitar commented Mar 7, 2024

Conceptually, why it is safe to delete OIDC session after authcode is exchanged, but not the regular session? Is this because for regular session it is still needed to be able to support refresh tokens?

@cfryanr
Copy link
Contributor Author

cfryanr commented Mar 7, 2024

There's not a "regular session" in the fosite storage interfaces. There are CreateAuthorizeCodeSession, CreatePKCERequestSession, CreateOpenIDConnectSession, CreateAccessTokenSession, CreateRefreshTokenSession (and maybe others?).

Each of those session storage types serve a different purpose and have a different lifecycle based on their purpose.

The data stored by CreateOpenIDConnectSession can only be read by calling GetOpenIDConnectSession. The only caller of GetOpenIDConnectSession is during authorization code exchange in flow_explicit_token.go. So if the authorization code exchange is successful, then nobody will ever call GetOpenIDConnectSession for that session ever again, so it is safe to call DeleteOpenIDConnectSession for it.

This lifecycle is approximately the same for the PKCE request session storage. That is also only needed during authcode exchange, and will never be needed again, so it is deleted.

However, this lifecycle is not the same for the other storage types.

Authorize code session storage lives beyond authcode exchange because fosite uses that as a place to store a true/false state that the authcode has already been exchanged. If another client later tries to exchange the same authcode again, fosite wants to treat that as a special case for security reasons.

Access token and refresh token session storage are both used during the refresh grant, so they need to live longer than the OpenID and PKCE session storage.

Is that what you were asking? Hope that helps.

@mitar
Copy link
Contributor

mitar commented Mar 7, 2024

Thanks!

@mitar
Copy link
Contributor

mitar commented Mar 7, 2024

(I am asking those questions in the context of #798.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants