You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Joachim Kanbach <jo...@gmx.de> on 2017/02/14 08:55:15 UTC

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

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.

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

Posted by Brian Demers <br...@gmail.com>.
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 <jo...@gmx.de> 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.
>