GitHub, LinkedIn, Twitter, Email

Spring Session JDBC Configuration

Tuesday, May 1, 2018

This article shows how to configure Spring Session to use database for session storage.

Please checkout the code from the following GitHub repository.

Table of contents

  1. Introduction
  2. Project setup
  3. Test


Before going into the more details of Spring Session configuration, I will share my view on the hype around Stateful vs Stateless session management.

Lately, a lot of people started using JSON Web Token (JWT) as a stateless mechanism for handling sessions. A couple of years ago I wrote an article on that topic and honestly didn't know that it will be abused by so many people. The main idea was to show how to override and extend various parts of Spring Security. I would strongly recommend not using JWT for handling sessions. Let's see what are the pros and cons of stateless and stateful session management approaches.



  1. No need to scale session data on the server-side as the session is maintained through cryptographically signed JSON Web Token (JWT).


  1. No log-out feature without introducing state on server side.
  2. Potential token explosion as JSON Web Token becomes larger.
  3. Sending JSON Web Token (JWT) payload on each request can be expensive.



  1. Ability to log-out user
  2. Out-of-box sliding session


  1. /

In short, don't use JSON Web Token to manage session data for your web applications. Most of the web applications will be fine with storing session-related data on Redis.

If you have microservices architecture, you can use API Gateway as a translation layer that would validate session-id and create a federated token to be used by the services. That's one use case where JSON Web Token fits nicely.

Project setup

Include spring-session-core and spring-session-jdbc in your pom.xml file.

Maven dependencies


Spring security configuration

The following class shows how to configure REST API security with the Spring Session:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;
private final AuthenticationProvider provider;

public WebSecurityConfig(final RestAuthenticationEntryPoint restAuthenticationEntryPoint,
final AuthenticationProvider provider) {
this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
this.provider = provider;

protected void configure(HttpSecurity http) throws Exception {
.successHandler(new SessionAuthenticationSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.defaultLogoutSuccessHandlerFor(new HttpStatusReturningLogoutSuccessHandler(),
new AntPathRequestMatcher("/logout"))
.requestCache(new NullRequestCache());

public HttpSessionIdResolver httpSessionIdResolver() {
return new HeaderHttpSessionIdResolver("X-Auth-Token");

protected void configure(AuthenticationManagerBuilder auth) {

The following list describes the WebSecurityConfig elements:

  1. RestAuthenticationEntryPoint - The entry point implementation which returns 401 status, indicating that the request requires authentication.
  2. SessionAuthenticationSuccessHandler - Success authentication handler that returns 200 status on successful authentication.
  3. HttpSessionIdResolver - Use HeaderHttpSessionIdResolver if you want to send authentication token through Http headers. Please check the following git commit regarding class name changes.
  4. @EnableJdbcHttpSession - This annotation is needed as it exposes SessionRepositoryFilter that will use the database for storing session data.


User login

Check for the x-auth-token in response and include it with the subsequent requests.

curl -X POST \
http://localhost:1999/login \
-H 'cache-control: no-cache' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F username=test \
-F password=test

User logout

curl -X GET \
http://localhost:1999/logout \
-H 'cache-control: no-cache' \
-H 'x-auth-token: 2eabcc45-0bb5-40f7-8d48-8aec0fdf0bbc'

Access to protected resource

This is an example of how to access the protected resource by including the access token in the headers:

curl -X GET \
http://localhost:1999/api/sample \
-H 'cache-control: no-cache' \
-H 'x-auth-token: 30ab6295-7b63-4172-9fb3-3514d5e46390'

Source code

Session Authentication Success Handler

public class SessionAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {


public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
public void commence(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, AuthenticationException e)
throws IOException, ServletException {

httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");


public class AuthenticationProviderConfig {
private final PasswordEncoder passwordEncoder;
private final UserDetailsService userDetailsService;

public AuthenticationProviderConfig(PasswordEncoder passwordEncoder,
@Qualifier("databaseUserDetailsService") UserDetailsService userDetailsService) {
this.passwordEncoder = passwordEncoder;
this.userDetailsService = userDetailsService;

public AuthenticationProvider databaseAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
return daoAuthenticationProvider;

Password encoder configuration

public class PasswordEncoderConfig {
protected PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);

← Home