Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-dev] Classloader issue reloading UserIdentity session attribute

Padraic,

Looks like the problem is that the thread that is doing the deserialization of the session is not a thread that has passed through the jetty handler hierarchy which happens eg on a request handling thread. A request handling thread will have a thread local set on it that is the context that relates to the request. The error you see on SessionAuthentication is caused because the thread doesn't know what context it is in, and thus has no SecurityHandler.

cheers
Jan

On Fri, 10 Sept 2021 at 13:39, Padraic Renaghan via jetty-dev <jetty-dev@xxxxxxxxxxx> wrote:

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

_______________________________________________
jetty-dev mailing list
jetty-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/jetty-dev


--
Jan Bartel <janb@xxxxxxxxxxx>
www.webtide.com
Expert assistance from the creators of Jetty and CometD


Back to the top