Hello all.
Now you might – by now – know that I’ve started working on small new project. It’s being secretively worked on in quiet corners, maybe the idea will die down, or maybe it’ll grow to the energy of one of those raging jungle fires. Who knows right now, only time will tell… This step is the next piece of the puzzle, fueling the idea’s “fire”. Given that the work is for the development of commercial project, I can only reveal some of the code that ties the application together.
For the past month or so, I’ve been fighting to get Google Guice and Apache Shiro to work together. Now within this time, Shiro has been transitioning from 1.1 (without native Guice support) to 1.2 that allows for simpler and more convenient dependency injection with Guice. I could get Shiro to work through manually inject dependencies, but that was too much work. On top of all, my efforts would have been wasted given that 1.2 was just round the corner.
So, I gave in to the hard shoulder of the road and started working with 1.2-SNAPSHOTS – Yes, it wasn’t one of my best decisions! However, now we have a 1.2 release and we can PARTAY! (sorry, just slightly happy!).
So for the sake of helping the community, and the thought of ‘anyone out there?’, I’m gonna share you some of the more straight forward code than the advice currently out there on the web (as on Stackoverflow for example). For a bit of background, this link is me trying desperately to get some answers.
So less talking, more coding…. Starting with the web.xml:
[web.xml]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>My App</display-name> <context-param> <description>Vaadin production mode</description> <param-name>productionMode</param-name> <param-value>false</param-value> </context-param> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>com.app.GuiceServletInjector</listener-class> </listener> </web-app> |
Now, your web.xml states that all requests should be answered through the ‘GuiceServletInjector’, and has to be filtered through the ‘GuiceFilter’. So how does your ‘GuiceServletInjector’ look a like:
[GuiceServletInjector.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class GuiceServletInjector extends GuiceServletContextListener { private ServletContext servletContext; @Override public void contextInitialized(ServletContextEvent servletContextEvent) { servletContext = servletContextEvent.getServletContext(); super.contextInitialized(servletContextEvent); } @Override protected Injector getInjector() { return Guice.createInjector(new ShiroConfigurationModule(servletContext), new GuiceServletModule()); } } |
Now, be aware that any other injectors that you might want need to be initiated before your servlet module. In my case, it is the Shiro Configuration module that I have created:
[ShiroConfigurationModule.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ShiroConfigurationModule extends ShiroWebModule { @Inject public ShiroConfigurationModule(ServletContext servletContext) { super(servletContext); } @Override protected void configureShiroWeb() { try { bindRealm().to(ShiroBaseRealm.class); } catch (Exception e) { e.printStackTrace(); } addFilterChain("/**", ANON); addFilterChain("/lock/**", AUTHC_BASIC, config(PERMS, "no")); } } |
This configuration file basically acts as if you have a ‘shiro.ini’ file. The reason why I didn’t like the ‘.ini’ configuration is that I want to have the code-flexibility. Also, I want my database details to be stored in the classes in the ‘.jar’ files rather than a configuration file in the ‘.jar’ file.
Also something you might have noticed is the use of a custom realm, I called ‘ShiroBaseRealm’. This acts as the main connector my database, although right now doesn’t have much code in it. For the sake of clarity, here is the code:
[ShiroBaseRealm.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class ShiroBaseRealm extends AuthorizingRealm { HashedCredentialsMatcher matcher; public ShiroBaseRealm() { matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME); } @Override public CredentialsMatcher getCredentialsMatcher() { return matcher; } @Override public boolean supports(AuthenticationToken token) { return true; // super.supports(token); } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); if (username == null) { throw new AccountException("Null usernames are not allowed by this realm."); } String password = "password"; return new SimpleAuthenticationInfo(username, password, this.getName()); } protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { if (principals == null) { throw new AuthorizationException("PrincipalCollection method argument cannot be null."); } String username = (String) principals.fromRealm(getName()).iterator().next(); Set roleNames = ImmutableSet.of(); if (username != null) { roleNames = ImmutableSet.of("foo", "goo"); } return new SimpleAuthorizationInfo(roleNames); } } |
And finally, the actual servlet module:
[GuiceServletModule.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class GuiceServletModule extends ServletModule { @Override protected void configureServlets() { super.configureServlets(); filter("/*").through(GuiceShiroFilter.class); // bind to database.... // once per session... bind(UIControllerService.class).to(GenericUIControllerServiceImpl.class).in(ServletScopes.SESSION); bind(Application.class).to(VaadinMainWindow.class).in(ServletScopes.SESSION); serve("/*").with(MyApp.class); } } |
Well, obviously this is just a starter to the Shiro world. I am personally planning to use AOP to ‘lock-down’ method calls within the code, since I am using Vaadin to create the website. Therefore I don’t really want to check whether a user is authenticated to call this method or not, and therefore the ‘@RequiresAuthentication’ comes very handy.
If you have any questions, let me know. But do also know that I am NOT an expert in this (yet!).
Good luck,
Mo.
7 Comments
Trackbacks/Pingbacks
- Using Guice, Shiro and Vaadin together | Security | Syngu - [...] How to use Apache Shiro and Google Guice together with Vaadin? Security ...

Hi Mo,
I’m trying to do the same thing you are… to integrate Vaadin and Shiro and finding that if I want to use annotations for authorization I need to use something like Guice or Spring.
I’m wondering if you have a sample app demonstrating the concepts you discuss in this article? I’m still having trouble understanding how to integrate all of this. I’m really hoping that you can help because, as you well know, there is very little information out there on this specific topic.
G
Hello.
I do have an app that does the thing you want. However, there are some major bugs with it as well as being for a commercial use (hence why I can’t share code directly).
However, I am very much willing to help out. First off, what are you having trouble with? The setup, compile time stuff, libraries, how they all link together?
I know how you are feeling since I’ve been there before, but once you get it all working, it’s a beautiful setup!
Mo.
Hi Mo,
I created a sample Vaadin project (v6.7.5) and I added my user libraries to the build path, including Guice and Shiro. I then started creating the classes and configuring according to your article.
I was having a heap of problems at that point and I posted by original question. I traced most of the issues to a missing (shiro-guice) jar so I corrected that and now I am left with a little confusion about how to tie this into Vaadin. It seems that it is happening in the GuiceServletModule.
bind(Application.class).to(SampleApplication.class).in (ServletScopes.SESSION);
serve(“/*”).with(???.class);
How does the HttpServlet relate to the Vaadin application? Am I missing something obvious here?
G
Ok sure. That’s the bit I didn’t include the code above. My bad. [I'll try and include more code for the future as soon as I can].
So you need to create a MyApp class that extends AbstractApplicationServlet. The constructor of this servlet will have to take in a Provider and return the (same) Application for every HttpServletRequests.
Needless to say that Provider will get injected so make sure you have @Inject on the constructor (it will get injected because you have already connected Application to SampleApplication).
Hopefully that should get you going and let you see something on the page. Afterwards you can then start to mess around with Shiro and method-level security.
Hi Mo,
Just a quick note… I managed to get that integration working sometime late last night. Thanks for your help! It’s very much appreciated.
G
Thanks, this is really useful – I’ve been looking at integrating these three libraries for a while but never got around to it. I’d love to read further insights into your use with Shiro and Vaadin like this.
Hey Simon.
Thanks! Sure I will put up some more blog posts when I can get Shiro to be a bit more useful, and figure out how to use its annotations!