Easy Session Sharing in Spring Boot with Spring Session and MySQL

This tutorial shows you how to configure Spring Session to distribute your session using MySQL

Session management in multi-node applications presents multiple challenges. When the architecture includes a load balancer, client requests might be routed to different servers each time, and the HTTP session might be lost. In this tutorial, we will walk you through the configuration of session sharing in a multi-node Spring Boot application.

Prerequisites:

Session Persistence

Session Persistence is a technique for sticking a client to a single server, using application layer information—like a cookie, for example. In this tutorial, we will implement session persistence with the help of HAProxy, a reliable, high performance, TCP/HTTP load balancer.

HAProxy logo

First, let’s create a web application with Okta authentication and run three nodes with HAProxy load balancing using Docker Compose.

Create a Maven project using the Spring Initializr’s API.

curl https://start.spring.io/starter.zip \
 -d dependencies=web,okta \
 -d groupId=com.okta.developer \
 -d artifactId=webapp \
 -d name="Web Application" \
 -d description="Demo Web Application" \
 -d packageName=com.okta.developer.webapp \
 -d javaVersion=11 \
 -o web-app.zip

Unzip the project:

unzip web-app.zip -d web-app
cd web-app

Run the Okta Maven Plugin to register a new account:

./mvnw com.okta:okta-maven-plugin:register

If you already have an Okta account registered, use login instead of register.

Then, configure your Spring application for authentication using Okta:

./mvnw com.okta:okta-maven-plugin:spring-boot

It will set up a new OIDC application for you and write your Okta settings to your src/main/resources/application.properties file.

Create a GreetingController at src/main/java/com/okta/developer/webapp/controller:

package com.okta.developer.webapp.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;

import java.net.InetAddress;

@Controller
public class GreetingController {

    private static final Logger logger = LoggerFactory.getLogger(GreetingController.class);

    @GetMapping(value = "/greeting")
    @ResponseBody
    public String getGreeting(@AuthenticationPrincipal OidcUser oidcUser) {
        String serverUsed = "unknown";
        try {
            InetAddress host = InetAddress.getLocalHost();
            serverUsed = host.getHostName();
        } catch (Exception e){
            logger.error("Could not get hostname", e);
        }
        String sessionId = RequestContextHolder.currentRequestAttributes().getSessionId();
        logger.info("Request responded by " + serverUsed);
        return "Hello " + oidcUser.getFullName() + ", your server is " + serverUsed + ", with sessionId " + sessionId;
    }
}

Run the application with:

./mvnw spring-boot:run

#mysql #spring-boot #java #programming #developer

Easy Session Sharing in Spring Boot with Spring Session and MySQL