Application Clustering This chapter is focused on clustering support for your own AS7, EAP6 or Wildfly applications, which are secured by Keycloak. We support various deployment scenarios according if your application is: stateless or stateful distributable (replicated http session) or non-distributable and just relying on sticky sessions provided by loadbalancer deployed on same or different cluster hosts where keycloak servers are deployed The situation is a bit tricky as application communicates with Keycloak directly within user's browser (for example redirecting to login screen), but there is also backend (out-of-bound) communication between keycloak and application, which is hidden from end-user and his browser and hence can't rely on sticky sessions.
Stateless token store By default, the servlet web application secured by Keycloak uses HTTP session to store information about authenticated user account. This means that this info could be replicated across cluster and your application will safely survive failover of some cluster node. However if you don't need or don't want to use HTTP Session, you may alternatively save all info about authenticated account into cookie. This is useful especially if your application is: stateless application without need of HTTP Session, but with requirement to be safe to failover of some cluster node stateful application, but you don't want sensitive token data to be saved in HTTP session stateless application relying on loadbalancer, which is not aware of sticky sessions (in this case cookie is your only way) To configure this, you can add this line to configuration of your adapter in WEB-INF/keycloak.json of your application: Default value of token-store is session, hence saving data in HTTP session. One disadvantage of cookie store is, that whole info about account is passed in cookie KEYCLOAK_ADAPTER_STATE in each HTTP request. Hence it's not the best for network performance.
Relative URI optimization In many deployment scenarios will be Keycloak and secured applications deployed on same cluster hosts. For this case Keycloak already provides option to use relative URI as value of option auth-server-url in WEB-INF/keycloak.json . In this case, the URI of Keycloak server is resolved from the URI of current request. For example if your loadbalancer is on https://loadbalancer.com/myapp and auth-server-url is /auth, then relative URI of Keycloak is resolved to be https://loadbalancer.com/auth . For cluster setup, it may be even better to use option auth-server-url-for-backend-request . This allows to configure that backend requests between Keycloak and your application will be sent directly to same cluster host without additional round-trip through loadbalancer. So for this, it's good to configure values in WEB-INF/keycloak.json like this: This would mean that browser requests (like redirecting to Keycloak login screen) will be still resolved relatively to current request URI like https://loadbalancer.com/myapp, but backend (out-of-bound) requests between keycloak and your app are sent always to same cluster host with application . Note that additionally to network optimization, you may not need "https" in this case as application and keycloak are communicating directly within same cluster host.
Admin URL configuration Admin URL for particular application can be configured in Keycloak admin console. It's used by Keycloak server to send backend requests to application for various tasks, like logout users or push revocation policies. For example logout of user from Keycloak works like this: User sends logout request from one of applications where he is logged. Then application will send logout request to Keycloak Keycloak server logout user in itself, and then it re-sends logout request by backend channel to all applications where user is logged. Keycloak is using admin URL for this. So logout is propagated to all apps. You may again use relative values for admin URL, but in cluster it may not be the best similarly like in previous section . Some examples of possible values of admin URL are: http://${jboss.host.name}:8080/myapp This is best choice if "myapp" is deployed on same cluster hosts like Keycloak and is distributable. In this case Keycloak server sends logout request to itself, hence no communication with loadbalancer or other cluster nodes and no additional network traffic. Note that since the application is distributable, the backend request sent by Keycloak could be served on any application cluster node as invalidation of HTTP Session on node1 will propagate the invalidation to other cluster nodes due to replicated HTTP sessions. http://${application.session.host}:8080/myapp Keycloak will track hosts where is particular HTTP Session served and it will send session invalidation message to proper cluster node. For example application is deployed on http://node1:8080/myapp and http://node2:8080/myapp . Now HTTP Session session1 is sticky-session served on cluster node node2 . When keycloak invalidates this session, it will send request directly to http://node2:8080/myapp . This is ideal configuration for distributable applications deployed on different host than keycloak or for non-distributable applications deployed either on same or different nodes than keycloak. Good thing is that it doesn't send requests through load-balancer and hence helps to reduce network traffic.
Registration of application nodes to Keycloak Previous section describes how can Keycloak send logout request to proper application node. However in some cases admin may want to propagate admin tasks to all registered cluster nodes, not just one of them. For example push new notBefore for realm or application, or logout all users from all applications on all cluster nodes. In this case Keycloak should be aware of all application cluster nodes, so it could send event to all of them. To achieve this, we support auto-discovery mechanism: Once new application node joins cluster, it sends registration request to Keycloak server The request may be re-sent to Keycloak in configured periodic intervals If Keycloak won't receive re-registration request within specified timeout (should be greater than period from point 2) then it automatically unregister particular node Node is also unregistered in Keycloak when it sends unregistration request, which is usually during node shutdown or application undeployment. This may not work properly for forced shutdown when undeployment listeners are not invoked, so here you need to rely on automatic unregistration from point 3 . Sending startup registrations and periodic re-registration is disabled by default, as it's main usecase is just cluster deployment. In WEB-INF/keycloak.json of your application, you can specify: which means that registration is sent at startup (accurately when 1st request is served by the application node) and then it's resent each 10 minutes. In Keycloak admin console you can specify the maximum node re-registration timeout (makes sense to have it bigger than register-node-period from adapter configuration for particular application). Also you can manually add and remove cluster nodes in admin console, which is useful if you don't want to rely on adapter's automatic registration or if you want to remove stale application nodes, which weren't unregistered (for example due to forced shutdown).
Refresh token in each request By default, application adapter tries to refresh access token when it's expired (period can be specified as Access Token Lifespan) . However if you don't want to rely on the fact, that Keycloak is able to successfully propagate admin events like logout to your application nodes, then you have possibility to configure adapter to refresh access token in each HTTP request. In WEB-INF/keycloak.json you can configure: Note that this has big performance impact. It's useful just if performance is not priority, but security is critical and you can't rely on logout and push notBefore propagation from Keycloak to applications.