Guest blog by XDEV – a German software company and active member of the Vaadin community. In this post, they introduce Extras for Spring Security (XDEV SSE)—a set of modules that simplify and enhance security in Spring applications.
Overview
XDEV SSE provides various modules which make it easier and safer to create or manage various security solutions in Spring apps, especially in distributed systems.
It adds features like remembering the user’s last identity provider, automatic logout checks, improved OAuth2/OIDC management, smoother frontend integration and remembering the login after a server restart.
It also secures system endpoints, avoids unnecessary sessions and comes with built-in metrics. Nearly everything can be overridden with a custom implementation or disabled if required.
OAuth2/OIDC
Related module documentation: oauth2-oidc
Most modern applications use OAuth2 with OpenID Connect (OIDC) on top for authentication. Spring Boot’s default implementation is quite good but it lacks a few features: Once logged in it’s never checked if the login is still valid.
This is problematic when e.g. an employee leaves the company and they can still access the application, which is a typical use case of our apps.
How can this be fixed?
Well, OIDC provides a feature called Back-Channel logout.
The overall solution is quite good however there are a few issues:
- You have to manually implement responding to a Back-Channel logout request which can be complex for distributed architectures
- You have to ensure that the “pushed” logout request always reaches your system
- This can be tricky when using distributed architectures
There is a simpler solution: Revalidating if the user still has access to the Identity Provider
.
XDEV SSE utilizes exactly this, by regularly checking if the user still has access.
By default it uses the lifetime of OIDC’s accessToken, which makes it also possible to define this behavior on the Identity Provider
.
Here is a full feature comparison:
Feature |
BackChannel based logout |
AccessToken Revalidation with XDEV SSE |
Implementation |
Manual implementation required |
XDEV SSE provides pre-defined classes; minimal effort |
Logout |
Logout request pushed by the Identity provider |
Regularly checked utilizing accessToken |
What happens if the Identity Provider is down? |
No centralized logout possible |
There is a transition period (default: 3h) when the server can’t be reached. Active logins will not be checked during this period. If the period expires and the server still can’t be reached, all users will be logged out due to security reasons |
Please note that it’s also possible to combine both mechanisms and use the best of both worlds.
How to tell the frontend that the user is logged out?
We usually use our applications with an UI framework/frontend for example Vaadin. We somehow need to tell this framework that the user was logged out.
For that XDEV SSE provides a ReloadCommunicator
that can be used to tell the frontend that some kind of action is required. The implementation for Vaadin is provided with the vaadin-module.
Automatically reselect the provider that was used for the last login
Assume that a user gets logged out because their session expired due to inactivity.
You have 1 identity provider in Spring Boot? No problem the user gets automatically redirected to that provider.
But what if you have at least 2 identity providers? Now the user is redirected to the selection of identity providers and has to select their identity provider again. The list might be long and at least one additional click is required, so this is kind of annoying for them.
But how about redirecting them directly to their last provider?
This is exactly what is possible in XDEV SSE with the addition of a few lines of code.
Safely managing OIDC authentication in a distributed system
Related module documentation: oauth2-oidc-remember-me
When a client/user tries to switch to another instance of the web app, e.g.
- after it/the server was restarted
- after being redirected to another node inside the cluster
it no longer recognizes the session and with that all authentication data.
You probably don’t want users to login every time you do a deployment or when a new instance is started in a cluster. Otherwise they might write their password on a note and stick it under their monitor because they have to enter it so often.
So, how can this situation be improved, so that there is a secure and comfortable login?
Existing options include:
- Persisting the session
- Using Remember-Me authentication
But these all have downsides as described in the documentation.
XDEV SSE provides the following solution which addresses most of the problems:
The key takeaways here are:
- If the persistent data/backend is breached, the data is useless for the attacker:
- The data is stored on the client which the attacker cannot access easily
- An attacker has to get both: The server encryption key (stored on server) and the client encryption keys (stored in database)
- The encryption keys can easily be rotated
- If the data is stolen from the browser/frontend it’s not readable for an attacker as they require the encryption keys from the backend
- Most logic after the deserialization is not needed. Revalidation is only required if the client was not seen for a longer time
If you are interested in how the encryption and storage works, feel free to checkout the crypto-symmetric and client-storage modules.
Securing Spring Boot Actuator
Related module documentation: web-sidecar-actuator
Spring Boot actuator exposes management operations as REST endpoints via HTTP.
There have been to many incidents where someone accidentally exposed these endpoints publicly into the internet, for example:
- Volkswagen
- TeleMessage
- This caused Spring Boot to change the availability of the Heapdump endpoint in version 3.5.0
web-sidecar-actuator
secures these endpoints by requiring authentication. It also allows for multiple users in combination with multiple endpoints, so that for example your monitoring system only has access to the prometheus endpoint and can’t do any heap dumps.
It also ensures that all requests that are not handled by actuator but passed to actuator paths are not further processed. This is helpful when having a custom servlet (like Vaadin), that doesn’t ignore these paths by default.
Otherwise this might result in a corrupted response where a mix of the Actuator “Authentication failed” response and the actual app response might be present.
Hosting static resources
Related module documentation: web-sidecar-common
XDEV SSE provides a mechanism to register publicly available stateless resources, like static files. This helps prevent creating sessions where they are not needed, for example for robots.txt.
Integration with Vaadin
Related module documentation: vaadin
Vaadin’s default WebSecurity implementation is improved in multiple aspects and enhanced with the previously mentioned possibilities of SSE:
- grants Spring Security full access control before any requests are processed by Vaadin
- only create (Vaadin) Sessions when really required as these are rather heavy (Vaadin stores the state of the UI in these)
- improves customization options
- contains a pre-defined Content Security Policy for Vaadin
- handles CSRF requests that should not be processed by Vaadin
- forces a page reload (for XHR requests) when the authentication expires
Metrics
Most modules provide additional metrics that can be utilized to monitor the system and narrow down problems, for example information about how many requests got rejected due to missing authentication.
The default implementation supplies the metrics to Spring Boot Actuator, however you can also provide your own custom implementation if you wish to do so.
An example representation using Grafana could look like this:
And that’s basically it. XDEV SSE is available as OpenSource Software on GitHub. If you liked the article feel free to give the repository a star.