Graylog2 / Graylog2/graylog2-server
Shiro Session CacheManger is not meant for distrubed usage
- Dominant language
- Java
- Stars
- 8.1k
- Forks
- 1.1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 217
Description
Graylog is using the `MemoryConstrainedCacheManager`
https://github.com/Graylog2/graylog2-server/blob/master/graylog2-server/src/main/java/org/graylog2/bindings/providers/DefaultSecurityManagerProvider.java#L88
Which is not meant to be used for a Graylog cluster:
https://shiro.apache.org/caching.html
> The [MemoryConstrainedCacheManager](https://shiro.apache.org/static/current/apidocs/org/apache/shiro/cache/MemoryConstrainedCacheManager.html) is a CacheManager implementation suitable for single-JVM production environments. It is not clustered/distributed, so if your application spans across more than one JVM (e.g. web app running on multiple web servers), and you want cache entries to be accessible across JVMs, you will need to use a distributed cache implement instead.
In a Graylog cluster, we can end up in a situation where a node receives requests for sessions
that are not in the nodes in-memory cache, and will not be stored there either.
This is due to the fact that the cache is only populated when the session is created or updated.
Requests that don't update the session (`X-Graylog-No-Session-Extension: true`)
will never add the session to the cache.
Not having the session the cache is very inefficient and requires up to 10 mongoDB lookups for the non-exisinting session
per request.
## Possible Solution
A simple workaround could be to update the session cache after every read:
```java
--- graylog2-server/src/main/java/org/graylog2/security/MongoDbSessionDAO.java
+++ graylog2-server/src/main/java/org/graylog2/security/MongoDbSessionDAO.java
@@ -78,7 +78,12 @@ public class MongoDbSessionDAO extends CachingSessionDAO {
// expired session or it was never there to begin with
return null;
}
- return getSimpleSession(sessionId, dbSession);
+ final SimpleSession simpleSession = getSimpleSession(sessionId, dbSession);
+ // If the session was created on a different cluster node, we need to cache it here as well.
+ // Caching only happens for CachingSessionDAO.create() and CachingSessionDAO.update()
+
+ cache(simpleSession, sessionId);
+ return simpleSession;
}
```
But maybe we should investigate the possibility of using a distributed cachemanager...
* Graylog Version: 5.1.0-SNAPSHOT (but that code is ancient)
Contributor guide
Assessment
This issue has not been assessed yet.