We have a Spring MVC application (4.0.5) with Spring Security (3.2.4) that includes CSRF protection, which works fine. Now we are adding the SAML security extension (spring-security-saml2-core 1.0.0), which causes a CSRF protection problem.
The metadata has been configured in SSOCircle and is trying to access http://localhost:8080/myapp on the SSOCircle login page. After authentication, the browser is redirected to http://localhost:8080/myapp/saml/SSO and generates an error:
HTTP Status 403 - The expected CSRF token was not found. Session expired?
If we disable CSRF protection, everything will work. How can we maintain CSRF protection and still use the SAML extension?
Before setting up the SAML extension, we used the login form, and the CSRF protection worked, and we did not receive an error in the JSP login, and it did not have a 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 registering the settings in DEBUG, here are the logs that occur immediately after successful authentication:
22.10.2014 16:54:17.374 [http-bio-8080-exec-8] DEBUG oswmsupport.MultipartFilter - Using MultipartResolver 'filterMultipartResolver' for MultipartFilter 22.10.2014 16:54:17.377 [http-bio-8080-exec-8] DEBUG osbfsDefaultListableBeanFactory - Returning cached instance of singleton bean 'filterMultipartResolver' 22.10.2014 16:54:17.788 [http-bio-8080-exec-8] DEBUG oswmsupport.MultipartFilter - Request [/epass/saml/SSO] is not a multipart request 22.10.2014 16:54:17.790 [http-bio-8080-exec-8] DEBUG osswumAntPathRequestMatcher - Checking match of request : '/saml/sso'; against '/resources/**' 22.10.2014 16:54:17.791 [http-bio-8080-exec-8] DEBUG ossecurity.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 ossecurity.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 ossecurity.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 osswcHttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT 22.10.2014 16:54:17.798 [http-bio-8080-exec-8] DEBUG osswcHttpSessionSecurityContextRepository - 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 ossecurity.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 osswhwriters.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.se curity.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@ 244a79ef 22.10.2014 16:54:17.802 [http-bio-8080-exec-8] DEBUG ossecurity.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 ossecurity.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 osswcHttpSessionSecurityContextRepository - 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 osswcSecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed