tldr; How are OIDC Tokens (access, id, refresh) technically persisted?
We are looking into switching from Spring Security OAuth to Keycloak as our OIDC-Provider.
Spring Security OAuth serializes Token Objects to store them in the DB. The problem here is that the serialVersionUID contains the Spring Security version number.
That means that all tokens will be invalidated when the version is upgraded.
For that reason I wanted to check how Keycloaks stores its Tokens. I didn’t find anything resembling a JWT in the Database though.
Q1: Where are the (OIDC-)Tokens stored?
Q2: Does the storing method lend itself to enduring through Keycloak upgrades?
I am not sure if you mean Keycloak server or adapter (application). The
Keycloak server doesn’t store tokens anywhere. It “stores” just sessions
into the infinispan cache. When the request is send to the Keycloak
server to OIDC Introspection endpoint, Keycloak is able to check if the
access token is valid based on the:
- session, which is in the token (session_state claim) must be still
valid and present on keycloak server
- access token should not be expired
- access token signature must be valid (access tokens in Keycloak are
JWT tokens signed by Keycloak private key)
During request to OIDC refreshToken endpoint, there are similar checks
for the refresh tokens as Keycloak refresh tokens are also internally
stored as OIDC.
The only thing, which is persisted to the DB in addition to the
infinispan are the OIDC offline tokens. And those OIDC offline tokens
are guaranteed to be present among server upgrades. In other words, if
you create offline token in Keycloak version 7, then you upgrade to
KEycloak version 8, the offline token should be possible to successfully
refresh in that new version.
First: I’m just talking about the server. I’m not even using any of the adapters. I just rely on the fact that it’s OIDC.
Ok, I think I get it … for the most part.
- Does that mean ID and Refresh Token depend on the user having an active session?
- A logout at the server would invalidate both, right?
- And that goes for all active tokens?
- This also goes for server restarts?
As per OAuth2 Spec, Access Token and Refresh Token do not have to be JWT (then the actual tokens would have to be persited), but the session approach relies on that.
- Is that something you can ignore in practice?
I understood OpenId as an extension of OAuth, where we just added a predefined scope with a corresponding resource server endpoint. But since that’s a delegation of authorization, it should be independent of an active resource owner session. I guess that’s not quite right…
The offline token seems to be what I assumed a refresh token to be.
- Effectively that means, that I can get a new access token via offline token anytime and then access the user info endpoint with said access token, correct?
That should work for me.