On Wed, May 15, 2013 at 4:36 AM, Laszlo Ferenczi <[email protected]>wrote:
> Thanks for the reply, I've did something along these lines to work it > around. > > Just as a note, this is not the "usual" way how a guice module is > constructed and therefore it increases the WTFs/minute during the initial > learning curve of the library. See > http://darrennolan.com/2009/12/18/the-only-valid-measurement-of-code-quality-wtfs-minute/:) > Guice users expects some flexibility regarding replacing or extending > library classes and the ability to use JIT bindings. > Is ther a particular reason why the ShiroModule(s) must be private ? > I decided to make it private for two reasons. 1. There are a number of bindings that it must have that really don't have any relevance outside of shiro, and I had hoped to only expose the bindings that an integrating application should be integrating with. 2. In order to retrofit Guice support to the existing shiro classes, I needed to do some wtf-ey things that I really didn't want leaking out into an applications global injector. > > Also, I'm trying to get my head around the ServletContext parameter of the > ShiroWebModule. Is there a reason why this must be passed to the > constructor ? Checked the code and I can see that it's bound to the context > but failed to see why is this neccessary. ServletContext is bound by the > standard ServletModule which is guaranteed to be in play since you need to > bind somewhere the web filter. Simply injecting Provider<ServletContext> > where needed should do the trick. > In retrospect, we should probably pass a Provider<ServletContext> into the constructor there. That would provide a lot more flexibility. My memory is slightly hazy here, but from what I recall, if I simply injected the ServletContext that was bound by the ServletModule, guice would spit out a warning about using a deprecated API. This was the best way that I could come up with at the time to avoid that. Suggestions are welcome. > For unit testing I'm creating the injector with a special guice-aware > runner. To test the RESTful API of my application I'm binding an embedded > Jetty server in the context which I can just simply inject and start from > the unit test code. In this model it's not possible to use ShiroWebModule > because of the hardcoded dependency on ServletContext (which is obviously > not available during injector creation) Since configureShiro() method is > final I can't even subclass and override this behavior. > > I use this in production with an embedded jetty server. We achieve this by instantiating the server, instantiating the ServletContextHandler, creating the injector (passing ServletContextHandler.getRoot() to ShiroWebModule), then getting the GuiceFilter from the injector and adding it to the ServletContextHandler. > Is there something I miss ? > I've been a bit absent from this list lately, but hopefully I'll be able to lend some more support. The fact that Shiro is so configurable and didn't include any sort of annotation-based DI from the start has made this a bit more complicated than would be nice. I'm hoping we can resolve most of that in 2.0. > Regards, > Laszlo > > -- > L > > > On Wed, May 15, 2013 at 8:40 AM, picpoc <[email protected]>wrote: > >> Hi, >> >> If you only want to override the AuthenticationStrategy, you can do >> something like that within your ShiroWebModule: >> protected void configureShiroWeb() >> { >> [...] >> bind( ModularRealmAuthenticator.class ); >> bind( Authenticator.class ).to( >> ModularRealmAuthenticator.class ); >> bind( AuthenticationStrategy.class ).to( >> <your_custom_strategy> ); >> } >> >> Because there is no direct dependency to the AuthenticationStrategy from >> the >> SecurityManager or the other shiro objects bound to Guice, only binding it >> will do nothing as nobody depends on it. So you must bind all the >> necessary >> objects to obtain a connected dependency graph (which generally starts >> from >> the SecurityManager or the Environment), for the AuthenticationStrategy it >> is simply: >> SecutityManager -> Authenticator -> AuthenticationStrategy >> >> And if in your graph, one of the "intermediary" node (like the >> Authenticator >> in the example above) is a class of your own (and thus will not be heard >> by >> the TypeListener), then you don't need the type listener just inject all >> needed shiro objects with @Inject they'll be available for injection if >> you >> bind your class within the private ShiroWebModule. >> >> Another subtlety to be carefull about: if you're familiar to Guice you may >> wonder why the binding to the Authenticator is done like: >> bind( ModularRealmAuthenticator.class ); >> bind( Authenticator.class ).to( >> ModularRealmAuthenticator.class ); >> instead of just: >> bind( Authenticator.class ).to( >> ModularRealmAuthenticator.class ); >> >> Because when omitting the first line Guice will have to create a Just In >> Time binding for the ModularRealmAuthenticator class (as the second line >> is >> in fact just a link between injection keys, it does not define a concrete >> binding). The JIT binding created will not be considered part of the >> ShiroModule, and because this module is private, the type listener won't >> listen on ModularRealmAuthenticator and thus nothing will be injected on >> its >> instances. >> >> So to sum-up, recommandations could be: >> * Ensure to have a connected dependency graph. >> * No JIT bindings. >> >> Regards. >> >> >> >> -- >> View this message in context: >> http://shiro-user.582556.n2.nabble.com/Guice-module-tp7578713p7578729.html >> Sent from the Shiro User mailing list archive at Nabble.com. >> > >
