Reputation: 2263
Keycloak configuration and data is stored in a relational database, which is usally persisted to the hard disk. This includes data like realm settings, users, group- and role-memberships, auth flows and so on. But the user sessions will only be stored in an ephemeral in-memory infinispan cache. Therefore the session data in this cache is lost, when the keycloak server restarts.
There are many reasons why a restart of the Keycloak server is required. Major OS upgrades, Keycloak server upgrades to new versions, applying changes to keycloak e-mail templates or re-scheduling keycloak pods to other worker nodes in kubernetes or other cloud-based environments.
How to persist the session data to survive restarts. Ideally without having to maintain a custom infinspan server or using keycloak "offline sessions".
One solution could be to simply use so-called keycloak "offline sessions", but these sessions also have huge disadvantages:
See: https://www.keycloak.org/docs/latest/server_admin/#_offline-access
Will this problem still be present when keycloak > 17 is out and uses the all new quarkus distribution? Because in the following articles claim goals like Container-First Approach, Zero-Downtime Upgrade and Storage re-architecture.
Upvotes: 14
Views: 3504
Reputation: 2263
With Keycloak 25, there is a preview feature “persistent user sessions”, which stores the user sessions in its database. If a session is not found in memory, it is loaded from the database, and the user can continue to use their session without the need to re-authenticate.
Source: https://www.keycloak.org/2024/06/persistent-user-sessions-in-preview.html
Upvotes: 0
Reputation: 410
As you already wrote in your question, using Infinispan would be the go-to solution. Infinispan can be used in two ways:
Only having Infinispan does not solve the session loss problem. But Infinispan caches can be backed by a database, e.g. a Postgres DB. Then sessions are stored in the ISPN cache and in a corresponding DB table. This can prevent session loss, both for the internal and the external Infinispan cluster.
So a solution to your problem could be to configure the internal ISPN caches to use a database persistence. This could look like this in your cache-ispn.xml:
<cache-container name="keycloak">
<!-- other config ... -->
<replicated-cache name="sessions">
<expiration/>
<persistence>
<string-keyed-jdbc-store xmlns="urn:infinispan:config:store:jdbc:14.0" dialect="POSTGRES">
<connection-pool
connection-url="${env.ISPN_DATABASE_CONNECTION_URL}"
username="${env.ISPN_DATABASE_USERNAME:ispn}"
password="${env.INFINISPAN_DB_OWNER_PASSWORD:ispn}"
driver="org.postgresql.Driver"
properties-file="conf/ispn/infinispan-cache.properties"/>
<string-keyed-table create-on-start="true" prefix="ispn">
<id-column name="id" type="VARCHAR(255)"/>
<data-column name="data" type="bytea"/>
<timestamp-column name="ts" type="BIGINT"/>
<segment-column name="seg" type="INT"/>
</string-keyed-table>
</string-keyed-jdbc-store>
</persistence>
</replicated-cache>
<!-- other config ... -->
</cache-container
Upvotes: 0