I have a custom session data store implementation backed by Redis.
Everything working except ability to reload UserIdentity session attribute.
For example, this works
- Start up Redis
- Start up one instance of Jetty server, using default L1 cache, and custom L2 redis cache
- Run an example servlet that implements a counter and sets as session attribute
- Stop Jetty instance (to flush L1 cache)
- Restart Jetty instance
- Refresh browser page, thus attempting to reconnect to same session
- Session is not found in L1
- Session loaded from L2 Redis successfully
- Session attribute counter resumes counting up from previous value ✅
That all works fine.
However if I login prior to shutting down Jetty, then restart Jetty, then attempt to reload that session I get an error of
2021-09-09 23:17:36.739:WARN :oejs.HttpChannel:qtp1798286609-22: /Home
java.lang.IllegalStateException: !UserIdentity
at org.eclipse.jetty.security.authentication.SessionAuthentication.getUserIdentity(SessionAuthentication.java:62)
at org.eclipse.jetty.security.authentication.FormAuthenticator.validateRequest(FormAuthenticator.java:323)
at org.eclipse.jetty.security.authentication.DeferredAuthentication.authenticate(DeferredAuthentication.java:58)
at org.eclipse.jetty.server.Request.getUserPrincipal(Request.java:1597)
Working back from that I see the issue is most likely when the UserIdentity session attribute is deserialized, I see the "!SecurityHandler" log
2021-09-09 23:17:36.724:DEBUG:oejss.SessionData:lettuce-nioEventLoop-4-1: Deserialize org.eclipse.jetty.security.UserIdentity isServerLoader=true serverLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@22d8cfe0 tccl=WebAppClassLoader{root}@29d89d5d
2021-09-09 23:17:36.726:DEBUG:oejsa.SessionAuthentication:lettuce-nioEventLoop-4-1: !SecurityHandler
Which comes from SessionAuthentication.readObject
SecurityHandler security = SecurityHandler.getCurrentSecurityHandler();
if (security == null)
{
if (LOG.isDebugEnabled())
LOG.debug("!SecurityHandler");
return;
}
I do notice that all the other session attributes, which all work, have isServerLoader=false
whereas UserIdentity has isServerLoader=true
For deserialization I used the FileSessionDataStore as a guide and have this
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
SessionData.deserializeAttributes(data, ois);
and for serialization I have
ObjectOutputStream oos = new ObjectOutputStream(out);
SessionData.serializeAttributes(value, oos);
Logging from the serialize is as follows, via a custom RedisCodec class, perhaps the Lettuce Redis client running it on an async netty event loop thread is a problem?
2021-09-09 23:17:06.021:DEBUG:oejss.SessionData:lettuce-nioEventLoop-4-1: Attribute org.eclipse.jetty.security.UserIdentity class=org.eclipse.jetty.security.authentication.SessionAuthentication isServerLoader=true
Any pointers would be appreciated
Thanks,
Padraic