We have a Spring MVC (4.0.5) application with Spring Security (3.2.4) which includes CSRF protection which works fine. We are now adding the SAML security extension (spring-security-saml2-core 1.0.0) which causes an issue with CSRF protection.
The metadata has been configured on SSOCircle and trying to access http://localhost:8080/myapp
directs to the login page on SSOCircle. After authentication, the browser redirects to http://localhost:8080/myapp/saml/SSO
and generates an error:
HTTP Status 403 - Expected CSRF token not found. Has your session expired?
If we turn off CSRF protection, everything works. How can we maintain CSRF protection and still use the SAML extension?
Before setting up the SAML extension, we used a login form and CSRF protection worked and we did not receive an error on the login JSP and it did not have the token.
Code before SAML:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/login", "/login.request", "/logout").permitAll()
.anyRequest()
.hasAnyAuthority("MyRole")
.and().formLogin()
.loginPage("/login.request").loginProcessingUrl("/login")
.failureUrl("/login.request?error").permitAll().and().logout()
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login.request");
}
Code with SAML:
@Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().disable();
http.httpBasic().authenticationEntryPoint(samlEntryPoint());
http.addFilterBefore(metadataGeneratorFilter(),
ChannelProcessingFilter.class).addFilterAfter(samlFilter(),
BasicAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers("/error").permitAll()
.antMatchers("/saml/**").permitAll()
.anyRequest()
.hasAnyAuthority("MyRole")
.anyRequest().authenticated();
http.logout().logoutSuccessUrl("/");
}
UPDATE
After re-enabling CSRF protection and setting logging to DEBUG, here are the logs that occur right after the successful authentication:
22.10.2014 16:54:17.374 [http-bio-8080-exec-8] DEBUG o.s.w.m.support.MultipartFilter -
Using MultipartResolver 'filterMultipartResolver' for MultipartFilter
22.10.2014 16:54:17.377 [http-bio-8080-exec-8] DEBUG o.s.b.f.s.DefaultListableBeanFactory -
Returning cached instance of singleton bean 'filterMultipartResolver'
22.10.2014 16:54:17.788 [http-bio-8080-exec-8] DEBUG o.s.w.m.support.MultipartFilter -
Request [/epass/saml/SSO] is not a multipart request
22.10.2014 16:54:17.790 [http-bio-8080-exec-8] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
Checking match of request : '/saml/sso'; against '/resources/**'
22.10.2014 16:54:17.791 [http-bio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy -
/saml/SSO at position 1 of 14 in additional filter chain; firing Filter: 'MetadataGeneratorFilter'
22.10.2014 16:54:17.793 [http-bio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy -
/saml/SSO at position 2 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
22.10.2014 16:54:17.795 [http-bio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy -
/saml/SSO at position 3 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
22.10.2014 16:54:17.797 [http-bio-8080-exec-8] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
HttpSession returned null object for SPRING_SECURITY_CONTEXT
22.10.2014 16:54:17.798 [http-bio-8080-exec-8] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@b08c9c9. A new one will be created.
22.10.2014 16:54:17.800 [http-bio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy -
/saml/SSO at position 4 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
22.10.2014 16:54:17.801 [http-bio-8080-exec-8] DEBUG o.s.s.w.h.writers.HstsHeaderWriter -
Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@244a79ef
22.10.2014 16:54:17.802 [http-bio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy -
/saml/SSO at position 5 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
22.10.2014 16:54:17.805 [http-bio-8080-exec-8] DEBUG o.s.security.web.csrf.CsrfFilter -
Invalid CSRF token found for `http://localhost:8080/myapp/saml/SSO`
22.10.2014 16:54:17.807 [http-bio-8080-exec-8] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
22.10.2014 16:54:17.808 [http-bio-8080-exec-8] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter -
SecurityContextHolder now cleared, as request processing completed