Previous blog post described how to make Wicket, Spring Security and Atmosphere work together. However, it covered only one part of the story - the blocking transport technique (e.g. long polling). We tried to enable non-blocking protocol and run instantly into several problems emerging mainly from the necessity to use Spring Security filter chain along with Wicket filter and Atmosphere servlet:
The problems were:
Atmosphere will initiate non-blocking transport only if you include some context.xml in META-INF or exclude atmosphere-compat-tomcat7 from your classpath. We encountered a problem with SpringSecurity SessionFixationProtectionStrategy as request.getSession(true) did not return new session but this was fixed by using newer version of Atmosphere runtime. Our respective pom.xml part looks like this:
Then we need to define the two filters inside AtmosphereHandler defined in atmosphere.xml. We decided to do it programmatically. Here is our atmosphere.xml
And the CustomAtmosphereHandler looks like this:
CustomAtmosphereHandler was inspired by Atmosphere ReflectorServletProcessor. It creates both SpringSecurity and Wicket filters programmatically. In case of Wicket it loads the application in the same manner as the org.apache.wicket.spring.SpringWebApplicationFactory.
Custom FilterConfig gives us control over init parameters. Interestingly, Wicket-Atmosphere integration uses in the mapping filter mapping path from InitParam instead of the filter path set on the WicketFilter. Thus we need to add the init param FILTER_MAPPING_PARAM. We decided to do it this way because otherwise we will have filter configuration scattered over CustomAtmosphereHandler and web.xml.
Our web.xml is then fairly simple:
The problems were:
- Spring Security authentication did not work with NIO (non-blocking) connector on Tomcat. My guess is that the filter was not applied.
- AtmosphereServlet is configurable via atmosphere.xml where you define AtmosphereHandlers. The problem is that you cannot define multiple filters similarly to web.xml.
- AtmosphereFramework has a regexp which is used to map request path to AtmosphereHandlers mapped to /*. It does not contain underscore which is part of default form-login processing-url of SpringSecurity (j_spring_security_check).
Let's see how we dealt with these problems.
First of all, install the newest version of Tomcat 7 as non-blocking support was developed rather recently and it may not work properly with older versions. We used Tomcat 7.0.34.
Modify the HTTP connector in server.xml
Atmosphere will initiate non-blocking transport only if you include some context.xml in META-INF or exclude atmosphere-compat-tomcat7 from your classpath. We encountered a problem with SpringSecurity SessionFixationProtectionStrategy as request.getSession(true) did not return new session but this was fixed by using newer version of Atmosphere runtime. Our respective pom.xml part looks like this:
Then we need to define the two filters inside AtmosphereHandler defined in atmosphere.xml. We decided to do it programmatically. Here is our atmosphere.xml
And the CustomAtmosphereHandler looks like this:
CustomAtmosphereHandler was inspired by Atmosphere ReflectorServletProcessor. It creates both SpringSecurity and Wicket filters programmatically. In case of Wicket it loads the application in the same manner as the org.apache.wicket.spring.SpringWebApplicationFactory.
Custom FilterConfig gives us control over init parameters. Interestingly, Wicket-Atmosphere integration uses in the mapping filter mapping path from InitParam instead of the filter path set on the WicketFilter. Thus we need to add the init param FILTER_MAPPING_PARAM. We decided to do it this way because otherwise we will have filter configuration scattered over CustomAtmosphereHandler and web.xml.
Our web.xml is then fairly simple:
Now one last finishing touch:) We need to alter default SpringSecurity path so that it is mapped to our CustomAtmosphereHandler so modify the form-login line in your spring-security.xml: