Hello Les, I think I now see why I shouldn't use my earlier method. But unfortunately I still can't get my head around how else to do it. Subject.Builder uses SecurityUtils to acquire a securityManager, either from the ThreadContext of the static VM one. And in my other ContextListener the ThreadContext has no security Manager,
Regarding you point about acquiring the environment, I can do that in contextInitialized with WebEnvironment wm = new EnvironmentLoader().initEnvironment(servletContextEvent.getServletContext()) ; Which will correctly configure a securityManager in ThreadContext on the current thread But if shiro has already been initialised with EnvironmentLoaderListener the above command will except with: "java.lang.IllegalStateException: There is already a Shiro environment associated with the current ServletContext" So to summarise my limited understanding 1) If the Environment is already set in the ServletContext I can access it in other ContextListeners but the securityManager in ThreadContext isn't set. And I can't create another environment as I get the above exception. 2) If the environment isn't already set I can create it with the code above and ThreadContext is configured and everything works. So at the moment I just can't see how I can get Multiply ContextListeners using Shiro. Cheers, Steven. (knows he's missing something but can't quite put his finger on it) From: "Les Hazlewood-2 [via Shiro User]" <[email protected]> Date: Thursday, 26 April 2012 19:02 To: Steven Pearce <[email protected]> Subject: Re: Implementing Shiro in a Listener [Documentation Submission] The EnvironmentLoaderListener only sets up Shiro's environment for a webapp (SecurityManager, filters, etc). The ShiroFilter is the component that uses the environment to construct Subject instances and make them available on the current thread at runtime. If other non-filtered components (like other Listeners) need a Shiro Subject, they must acquire the Environment and create a Subject instance to use themselves. As a warning, I should note that your example works, but probably only as a side effect that the same thread used to initialize Shiro happens to be the same thread that initializes your other Servlet Context Listener. It is possible that the thread used to shut down the listener is not the same as the one that initialized it, so the ThreadContext.remove() call might not do anything meaningful. The ThreadContext is a low-level infrastructural component used by Shiro's internals and should only be referenced directly in very specific circumstances. Most of the time using the Subject.Builder and calling execute on the built subject (subject.execute(work)) is the 'safe' way to guarantee thread cleanup. This same technique (subject.execute) is used by the ShiroFilter for example: http://shiro.apache.org/static/current/apidocs/src-html/org/apache/shiro/web /servlet/AbstractShiroFilter.html#line.362 This should ideally be repeated by other infrastructural components when possible to guarantee thread cleanup. Thanks for the post! Cheers, -- Les Hazlewood CTO, Stormpath | http://stormpath.com | 888.391.5282 twitter: @lhazlewood | http://twitter.com/lhazlewood blog: http://leshazlewood.com stormpath blog: http://www.stormpath.com/blog On Thu, Apr 26, 2012 at 6:37 AM, Stexxen <[hidden email] </user/SendEmail.jtp?type=node&node=7503722&i=0> > wrote: > Hi, > I have been struggling with getting Shiro working in another Listener in > Tomcat. I finally got it working so I am writing what I found here. > > Within web.xml I have the usual EnvironmentLoaderListener > <listener> > > <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-cla ss> > </listener> > > I also have another Listener > <listener> > <listener-class>org.somethingelse.OtherClass</listener-class> > </listener> > > Any code executed by OtherClass couldn't get a Subject because the > ThreadContext.getSecurityManager returned null. Whenever you executed > SecurityUtils.getSubject() you would get the following exception > > > org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager > accessible to the calling code, either bound to the > org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an > invalid application configuration. > > To resolve I had to populate the ThreadContext in OtherClass, > Within OtherClass:contextInitialized > > WebEnvironment wm = > WebUtils.getRequiredWebEnvironment(servletContextEvent.getServletContext()); > WebSecurityManager wsm = wm.getWebSecurityManager(); > ThreadContext.bind(wsm); > > and in OtherClass:contextDestroyed > ThreadContext.unbindSecurityManager(); > ThreadContext.remove(); > > Now any calls to SecurityUtils.getSubject() would return a Subject. > > Hope this may help someone in future. > > Now the thought has crossed my mind that I have missed some vital part of > the documentation that would make what I have done above unnecessary. If so > please let me know what it is. > > Thanks, > S. If you reply to this email, your message will be added to the discussion below: http://shiro-user.582556.n2.nabble.com/Implementing-Shiro-in-a-Listener-Docu mentation-Submission-tp7502910p7503722.html To unsubscribe from Implementing Shiro in a Listener [Documentation Submission], click here <http://shiro-user.582556.n2.nabble.com/template/NamlServlet.jtp?macro=unsub scribe_by_code&node=7502910&code=c3RldmVuLnBlYXJjZUBpbmNsb3Vkb25lLmNvbXw3NTA yOTEwfC0yOTU1MzA0Mg==> . NAML <http://shiro-user.582556.n2.nabble.com/template/NamlServlet.jtp?macro=macro _viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.Ba sicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.templa te.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instan t_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml> -- View this message in context: http://shiro-user.582556.n2.nabble.com/Implementing-Shiro-in-a-Listener-Documentation-Submission-tp7502910p7504030.html Sent from the Shiro User mailing list archive at Nabble.com.
