Affects: all version
When using org.springframework.web.server.session.InMemoryWebSessionStore as the session cache for web login, the getSessions()method returns Collections#unmodifiableMap(Map).
public Map<String, WebSession> getSessions() {
return Collections.unmodifiableMap(this.sessions);
}
I want to achieve mandatory logout for all users by clearing the session, but since the Map is immutable, I cannot execute the Map#clear() method. What should be done if I want to batch invalidate a session.
Comment From: bclozel
This is done on purpose, to adhere to the WebSessionStore contract. WebSessionStore implementations aren't all supposed to give you a way to list all persisted sessions (especially if storage is distributed).
If you want to batch remove sessions, you can do the following:
Set<String> sessionIds = this.store.getSessions().keySet();
Flux.fromIterable(sessionIds)
.flatMap(sessionId -> this.store.removeSession(sessionId))
.blockLast();
If you'd like to selectively invalidate sessions, you can do this:
Set<String> sessionIds = this.store.getSessions().keySet();
Flux.fromIterable(sessionIds)
.filter(sessionId -> ...) // filter sessions based on your criteria?
.flatMap(sessionId -> this.store.retrieveSession(sessionId))
.map(webSession -> webSession.invalidate())
.blockLast();
Note: I used a blocking operator in this code snippet, but you shouldn't block in the middle of a reactive pipeline and should probably use .then() and connect this to the rest of your pipeline.
For more questions, please use StackOverflow. Thanks!
Comment From: zk1991-github
I understand whether the efficiency of removing a session through traversal is too low. This type of storage is mainly aimed at standalone applications rather than distributed applications, so can the issue of distribution be ignored. Returning Session as ConcurrentHashMap facilitates efficient execution of clearing functions. thanks