Issue
How can I create a session in a spring mvc application from a given ID instead of a generated one?
I want to fixate the session. The fixation will be started by a trusted ui service. This trusted service forwards all requests. Thus the fixation can't begin in browser. It is not intended to do it without this ui service.
Providing a HttpSessionIdResolver bean does not work, since it only changes the location in HTTP response. Eg Session ID in HTTP header after authorization.
Are there any solutions without creating a shadow session management?
Session is required for keycloak integration. Guess it's not possible to use keycloak in stateless mode.
Thanks in advance
Solution
It is possible to fixate a session with spring-session.
@Configuration
@EnableSpringHttpSession
public class SessionConfig {
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return new HttpSessionIdResolver() {
public List<String> resolveSessionIds(HttpServletRequest request) {
final var sessionId = request.getHeader("X-SessionId");
request.setAttribute(SessionConfig.class.getName() + "SessionIdAttr", sessionId);
return List.of(sessionId);
}
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {}
public void expireSession(HttpServletRequest request, HttpServletResponse response) {}
};
}
@Bean
public SessionRepository<MapSession> sessionRepository() {
return new MapSessionRepository(new HashMap<>()) {
@Override
public MapSession createSession() {
var sessionId =
(String)RequestContextHolder
.currentRequestAttributes()
.getAttribute(SessionConfig.class.getName()+"SessionIdAttr", 0);
final var session = super.createSession();
if (sessionId != null) {
session.setId(sessionId);
}
return session;
}
};
}
In #resolveSessionIds()
you can read the ID and store for later use.
createSession()
is called when no session has been found and a new one is required. Here you can create the session with previously remembered ID in MapSession#setId(String)
.
Even if is possible, IMO it is not a good idea. There might be other architectural solutions/problems.
Answered By - Paul
Answer Checked By - David Goodson (JavaFixing Volunteer)