I'm working on a Java application where a user registers a password for his/her account. The following are being used:
- Spring Boot
- Spring MVC
- Spring Web Flow
- Spring Security
- Thymeleaf
- Interceptor (for checking the session in the
preHandlemethod)
For the Spring Security part, there's really no authentication required. I just use it to handle CSRF and the configuration is as follows:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// CSRF feature only
http.authorizeRequests().anyRequest().permitAll();
}
}
Now, this is where things get messy. When I deploy it to Tomcat in a Unix environment, ;jsessionid gets appended to the URL and Spring Security is not happy. I have scrounged the Internet and found the following solutions to remove it (alongside my results).
server.servlet.session.tracking-modes=cookie in application.properties does nothing.
web.xml
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
or
@Configuration
public class WebConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
HashSet<SessionTrackingMode> set = new HashSet<>();
set.add(SessionTrackingMode.COOKIE);
servletContext.setSessionTrackingModes(set);
}
}
yields an IllegalArgumentException: The session tracking mode [COOKIE] requested for context [/<context-name>] is not supported by that context
I'm about to pull what remains of my hair off so I reverted any cookie-related changes and thought of just allowing semicolons in the URL (I know, I know, not secure) using the snippet below in the same SecurityConfig class.
@Bean
public HttpFirewall allowUrlSemicolonHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
return firewall;
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.httpFirewall(allowUrlSemicolonHttpFirewall());
}
And voila! The web flow runs on an infinite redirect.
Questions:
- Has anyone ever encountered
IllegalArgumentException: The session tracking mode [COOKIE] requested for context [/<context-name>] is not supported by that contextbefore? I've searched far and wide and the closest that I could find is this. - Could the reason behind
server.servlet.session.tracking-modes=cookienot working be the same as above? - Could the infinite redirect be caused by
http.authorizeRequests().anyRequest().permitAll()? I tried usinganonymous()but the result was the same. - Is it possible to know which part exactly is causing the infinite redirect?
Please note that allowing semicolons in the URL is working fine and dandy in my localhost, so I have a hunch that what's causing the redirects is SSL-related. In the same way that locally ;jsessionid is not being appended to the URL.
My next step is to try configuring SSL locally in an attempt to replicate the issue. In the meantime, any help would be highly appreciated. My apologies if there's too much information here; I'm willing to repost it as multiple questions if that's necessary.
Answering this one myself as further development this year actually led to a solution from a teammate of mine when he extended the base code to a new application which required Spring Security. Turns out the persistent
jsessionidin our case was due to thecookiesattribute below in our Tomcatcontext.xml.On the Java side, the generic security configuration below (for the original application) worked even with the Tomcat configuration above.