Search code examples
javaapachejettyguiceshiro

Configuring Shiro with Guice without a ServletContext


I'm using Guice to wire a Jetty server and I want to add some security with Apache Shiro.

It seems Shiro needs a ServletContext to be configured, but the problem is I don;t have a ServletContext at the configuration time (for example in a ServletModule as the documentation states). The ServletContext is available in GuiceServletContextListener, but at this time, my injector is already created so it's to late to install the Shiro module.

I tried to provide the ServletContext to Shiro through a Guice provider, (Provider<ServletContext>) but still without success. I thought this provider will serve the ServletContext after its creation. This also gives a WARNING:

"com.google.inject.servlet.InternalServletModule$BackwardsCompatibleServletContextProvider get
WARNING: You are attempting to use a deprecated API (specifically, attempting to @Inject ServletContext inside an eagerly created singleton. While we allow this for backwards compatibility, be warned that this MAY have unexpected behavior if you have more than one injector (with ServletModule) running in the same JVM."

How could one install the Shiro Web module after the injector is created?


Solution

  • The standard way to get the ServletContext is to extend the GuiceServletContextListener.

    Imho a major oversight of the API.

    http://code.google.com/p/google-guice/issues/detail?id=603

    There is also a tutorial here:

    https://issues.apache.org/jira/browse/SHIRO-320

    (Edit: after reading comments) You have 2 options:

    1. Refacture code to only create the injector in GuiceServletContextListener
    2. Use a child injector (tricky)

    With Child Injector only instances created by the child injector will get the "Shiroed". Keep in mind: Just-in-time bindings created for child injectors will be created in an ancestor injector whenever possible.

    Things will work as expected for your Servlets and Filters but if you have business logic in your already created Injector they will not see Shiro. You can workaround this in a couple ways...