Quantcast

Inheritance of Security-Context causes problems in EJB-container

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inheritance of Security-Context causes problems in EJB-container

Daniel Lechner
I ran into a problem when using Shiro in a webapplication running on a JEE7-container (Wildfly 8). I'm not sure if this is an issue of the application server or Shiro. You can find the ongoing discussion for Wildfly under https://community.jboss.org/thread/239310

For those who do not want to read the forum-thread: If I use the webinterface of my application, Shiro wraps the request because of the registered filter and stores some information via the class ThreadContext in an InheritableThreadLocal variable. At some point, the application server may decide to spawn new threads (e.g. to work on asynchronous EJB-methods), if they have not been created and pooled so far.
Since Shiro uses an InheritableThreadLocal variable instead of a ThreadLocal one, this child process inherits the security-related information from the parent thread. After the web request is finished, Shiro removes it's information from the InheritableThreadLocal variable of the current thread, but of course cannot remove it from the spawned one. Since the child-thread is pooled, it may be used later for another task but still contains the stored security-information from the initial web request.

So the question is: why uses Shiro InheritableThreadLocal instead of ThreadLocal (as written in the Wildfly-forum, it is used since August 2007)?

Is there any chance to get rid of this problem? Is this a Shrio issue?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inheritance of Security-Context causes problems in EJB-container

Brian Demers
Here is some related info on this:

Looks like there is talk of Wildfly fixing the thread creation on the forum.

I feel like this is the expected behavior of Shiro, (async threads could be kicked off intentionally)

Are there any other containers that have the same issue?




On Thu, Apr 3, 2014 at 3:04 AM, Daniel Lechner <[hidden email]> wrote:
I ran into a problem when using Shiro in a webapplication running on a
JEE7-container (Wildfly 8). I'm not sure if this is an issue of the
application server or Shiro. You can find the ongoing discussion for Wildfly
under https://community.jboss.org/thread/239310

For those who do not want to read the forum-thread: If I use the
webinterface of my application, Shiro wraps the request because of the
registered filter and stores some information via the class ThreadContext in
an InheritableThreadLocal variable. At some point, the application server
may decide to spawn new threads (e.g. to work on asynchronous EJB-methods),
if they have not been created and pooled so far.
Since Shiro uses an InheritableThreadLocal variable instead of a ThreadLocal
one, this child process inherits the security-related information from the
parent thread. After the web request is finished, Shiro removes it's
information from the InheritableThreadLocal variable of the current thread,
but of course cannot remove it from the spawned one. Since the child-thread
is pooled, it may be used later for another task but still contains the
stored security-information from the initial web request.

So the question is: why uses Shiro InheritableThreadLocal instead of
ThreadLocal (as written in the Wildfly-forum, it is used since August 2007)?

Is there any chance to get rid of this problem? Is this a Shrio issue?



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Inheritance-of-Security-Context-causes-problems-in-EJB-container-tp7579859.html
Sent from the Shiro User mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inheritance of Security-Context causes problems in EJB-container

Joachim Kanbach
We're using asynchronous servlet processing in GlassFish 4.1 and we're faced with a related issue.

The code basically looks like this:


final AsyncContext aContext = servletRequest.startAsync();

Runnable asyncWrapper = new Runnable()
{
   @Override
   public void run()
   {
      try
      {
         // asynchronous processing here
         [...]
      }
      finally
      {
         aContext.complete();
      }
   }
}

Runnable subjectAwareAsyncWrapper = subject.associateWith( asyncWrapper );
aContext.start(subjectAwareAsyncWrapper);


GlassFish/Grizzly uses a ThreadPool for those Runnables passed off to AsyncContext.start(). Upon server shutdown/application undeployment, several (up to the number of threads configured for that pool) log entries like this appear:

2017-02-14T09:36:08.029+0100|Severe: The web application [...] created a ThreadLocal with key of type [org.apache.shiro.util.ThreadContext.InheritableThreadLocalMap] (value [org.apache.shiro.util.ThreadContext$InheritableThreadLocalMap@18959aa]) and a value of type [java.util.HashMap] (value [{org.apache.shiro.util.ThreadContext_SECURITY_MANAGER_KEY=org.apache.shiro.web.mgt.DefaultWebSecurityManager@814456, org.apache.shiro.util.ThreadContext_SUBJECT_KEY=org.apache.shiro.web.subject.support.WebDelegatingSubject@d727c0}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

To me, it looks like this is happening:

The threads spawned by the thread pool inherit Shiro's InheritableThreadLocals, as described by Daniel before. Then at a later point, the SubjectRunnable created by subject.associateWith() calls threadState.bind() in its run() method. The implementation of bind() of the associated SubjectThreadState does this:

this.originalResources = ThreadContext.getResources();

Since the thread at that point already has Shiro's InheritableThreadLocalMap associated with it, this is regarded as its "originalResources". And when SubjectRunnable calls threadState.restore() at the end of its run() method, SubjectThreadState restores those originalResources. So eventually all the threads in the thread pool will be associated with Shiro's InheritableThreadLocalMap, leading to the logged error.

I don't know if that is standard or discouraged behaviour, but the threads in that ThreadPool are apparently only created on demand by GlassFish, i.e. not in advance on server startup. I guess that is the reason why the concept with originalResources fails here.

I'm thinking of subclassing SubjectRunnable and replacing threadState.restore() in the run() method with threadState.clear() as a workaround.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inheritance of Security-Context causes problems in EJB-container

Brian Demers
We should probably start a new thread for this.  I found a couple examples on the web that do something similar to this, to access objects from the request/session

public class ShiroConfigurator extends ServerEndpointConfig.Configurator {

@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {

Subject subject = SecurityUtils.getSubject();
sec.getUserProperties().put(Subject.class.getName(), subject);

super.modifyHandshake(sec, request, response);
}
}

On Tue, Feb 14, 2017 at 3:55 AM, Joachim Kanbach <[hidden email]> wrote:
We're using asynchronous servlet processing in GlassFish 4.1 and we're faced
with a related issue.

The code basically looks like this:


final AsyncContext aContext = servletRequest.startAsync();

Runnable asyncWrapper = new Runnable()
{
   @Override
   public void run()
   {
      try
      {
         // asynchronous processing here
         [...]
      }
      finally
      {
         aContext.complete();
      }
   }
}

Runnable subjectAwareAsyncWrapper = subject.associateWith( asyncWrapper );
aContext.start(subjectAwareAsyncWrapper);


GlassFish/Grizzly uses a ThreadPool for those Runnables passed off to
AsyncContext.start(). Upon server shutdown/application undeployment, several
(up to the number of threads configured for that pool) log entries like this
appear:

2017-02-14T09:36:08.029+0100|Severe: The web application [...] created a
ThreadLocal with key of type
[org.apache.shiro.util.ThreadContext.InheritableThreadLocalMap] (value
[org.apache.shiro.util.ThreadContext$InheritableThreadLocalMap@18959aa]) and
a value of type [java.util.HashMap] (value
[{org.apache.shiro.util.ThreadContext_SECURITY_MANAGER_KEY=org.apache.shiro.web.mgt.DefaultWebSecurityManager@814456,
org.apache.shiro.util.ThreadContext_SUBJECT_KEY=org.apache.shiro.web.subject.support.WebDelegatingSubject@d727c0}])
but failed to remove it when the web application was stopped. Threads are
going to be renewed over time to try and avoid a probable memory leak.

To me, it looks like this is happening:

The threads spawned by the thread pool inherit Shiro's
InheritableThreadLocals, as described by Daniel before. Then at a later
point, the SubjectRunnable created by subject.associateWith() calls
threadState.bind() in its run() method. The implementation of bind() of the
associated SubjectThreadState does this:

this.originalResources = ThreadContext.getResources();

Since the thread at that point already has Shiro's InheritableThreadLocalMap
associated with it, this is regarded as its "originalResources". And when
SubjectRunnable calls threadState.restore() at the end of its run() method,
SubjectThreadState restores those originalResources. So eventually all the
threads in the thread pool will be associated with Shiro's
InheritableThreadLocalMap, leading to the logged error.

I don't know if that is standard or discouraged behaviour, but the threads
in that ThreadPool are apparently only created on demand by GlassFish, i.e.
not in advance on server startup. I guess that is the reason why the concept
with originalResources fails here.

I'm thinking of subclassing SubjectRunnable and replacing
threadState.restore() in the run() method with threadState.clear() as a
workaround.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Inheritance-of-Security-Context-causes-problems-in-EJB-container-tp7579859p7581499.html
Sent from the Shiro User mailing list archive at Nabble.com.

Loading...