110 lines
No EOL
6.5 KiB
Text
110 lines
No EOL
6.5 KiB
Text
[[_applicationclustering]]
|
|
=== Application Clustering
|
|
|
|
This chapter is related to supporting clustered applications deployed to JBoss EAP{% if book.community %}, WildFly and JBoss AS{% endif %}.
|
|
|
|
There are several options depending on if your application is:
|
|
|
|
* Stateless or stateful
|
|
* Distributable (replicated http session) or non-distributable
|
|
* Relying on sticky sessions provided by load balancer
|
|
* Hosted on same domain as {{book.project.name}}
|
|
|
|
Dealing with clustering is not quite as simple as for a regular application. Mainly due to the fact that both the browser and the server-side application
|
|
sends requests to {{book.project.name}}, so it's not as simple as enabling sticky sessions on your load balancer.
|
|
|
|
==== Stateless token store
|
|
|
|
By default, the web application secured by {{book.project.name}} uses the HTTP session to store security context. This means that you either have to
|
|
enable sticky sessions or replicate the HTTP session.
|
|
|
|
As an alternative to storing the security context in the HTTP session the adapter can be configured to store this in a cookie instead. This is useful if you want
|
|
to make your application stateless or if you don't want to store the security context in the HTTP session.
|
|
|
|
To use the cookie store for saving the security context, edit your applications `WEB-INF/keycloak.json` and add:
|
|
[source,json]
|
|
----
|
|
"token-store": "cookie"
|
|
----
|
|
|
|
NOTE: The default value for `token-store` is `session`, which stores the security context in the HTTP session.
|
|
|
|
One limitation of using the cookie store is that the whole security context is passed in the cookie for every HTTP request. This may impact performance.
|
|
|
|
Another small limitation is limited support for Single-Sign Out. It works without issues if you init servlet logout (HttpServletRequest.logout) from the
|
|
application itself as the adapter will delete the KEYCLOAK_ADAPTER_STATE cookie. However, back-channel logout initialized from a different application isn't
|
|
propagated by {{book.project.name}} to applications using cookie store. Hence it's recommended to use a short value for the access token timeout (for example 1 minute).
|
|
|
|
==== Relative URI optimization
|
|
|
|
In deployment scenarios where {{book.project.name}} and the application is hosted on the same domain (through a reverse proxy or load balancer) it can be
|
|
convenient to use relative URI options in your client configuration.
|
|
|
|
With relative URIs the URI is resolved as relative to the URL of the URL used to access {{book.project.name}}.
|
|
|
|
For example if the URL to your application is `https://acme.org/myapp` and the URL to {{book.project.name}} is `https://acme.org/auth`, then you can use
|
|
the redirect-uri `/myapp` instead of `https://acme.org/myapp`.
|
|
|
|
==== Admin URL configuration
|
|
|
|
Admin URL for a particular client can be configured in the {{book.project.name}} Administration Console.
|
|
It's used by the {{book.project.name}} server to send backend requests to the application for various tasks, like logout users or push revocation policies.
|
|
|
|
For example the way backchannel logout works is:
|
|
|
|
. User sends logout request from one application
|
|
. The application sends logout request to {{book.project.name}}
|
|
. The {{book.project.name}} server invalidates the user session
|
|
. The {{book.project.name}} server then sends a backchannel request to application with an admin url that are associated with the session
|
|
. When an application receives the logout request it invalidates the corresponding HTTP session
|
|
|
|
If admin URL contains `${application.session.host}` it will be replaced with the URL to the node associated with the HTTP session.
|
|
|
|
[[_registration_app_nodes]]
|
|
==== Registration of application nodes
|
|
|
|
The previous section describes how {{book.project.name}} can send logout request to node associated with a specific HTTP session.
|
|
However, in some cases admin may want to propagate admin tasks to all registered cluster nodes, not just one of them.
|
|
For example to push a new not before policy to the application or to logout all users from the application.
|
|
|
|
In this case {{book.project.name}} needs to be aware of all application cluster nodes, so it can send the event to all of them.
|
|
To achieve this, we support auto-discovery mechanism:
|
|
|
|
. When a new application node joins the cluster, it sends a registration request to the {{book.project.name}} server
|
|
. The request may be re-sent to {{book.project.name}} in configured periodic intervals
|
|
. If the {{book.project.name}} server doesn't receive a re-registration request within a specified timeout then it automatically unregisters the specific node
|
|
. The node is also unregistered in {{book.project.name}} when it sends an 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, which results in the need for automatic unregistration
|
|
|
|
Sending startup registrations and periodic re-registration is disabled by default as it's only required for some clustered applications.
|
|
|
|
To enable the feature edit the `WEB-INF/keycloak.json` file for your application and add:
|
|
|
|
[source]
|
|
----
|
|
"register-node-at-startup": true,
|
|
"register-node-period": 600,
|
|
----
|
|
|
|
This means the adapter will send the registration request on startup and re-register every 10 minutes.
|
|
|
|
In the {{book.project.name}} Administration Console you can specify the maximum node re-registration timeout (should be larger than _register-node-period_ from
|
|
the adapter configuration). You can also manually add and remove cluster nodes in through the Adminstration Console, which is useful if you don't want to rely
|
|
on the automatic registration feature or if you want to remove stale application nodes in the event your not using the automatic unregistration feature.
|
|
|
|
[[_refresh_token_each_req]]
|
|
==== Refresh token in each request
|
|
|
|
By default the application adapter will only refresh the access token when it's expired. However, you can also configure the adapter to refresh the token on every
|
|
request. This may have a performance impact as your application will send more requests to the {{book.project.name}} server.
|
|
|
|
To enable the feature edit the `WEB-INF/keycloak.json` file for your application and add:
|
|
|
|
[source]
|
|
----
|
|
"always-refresh-token": true
|
|
----
|
|
|
|
NOTE: This may have a significant impact on performance. Only enable this feature if you can't rely on backchannel messages to propagate logout and not before
|
|
policies. Another thing to consider is that by default access tokens has a short expiration so even if logout is not propagated the token will expire within
|
|
minutes of the logout. |