2014-10-22 11 views
5

हमारे पास वसंत सुरक्षा (3.2.4) के साथ एक स्प्रिंग एमवीसी (4.0.5) एप्लिकेशन है जिसमें सीएसआरएफ सुरक्षा शामिल है जो ठीक काम करती है। अब हम एसएएमएल सुरक्षा विस्तार (वसंत-सुरक्षा-सैम 2-कोर 1.0.0) जोड़ रहे हैं जो सीएसआरएफ सुरक्षा के साथ एक मुद्दा का कारण बनता है।स्प्रिंग एसएएमएल एक्सटेंशन और स्प्रिंग सिक्योरिटी सीएसआरएफ सुरक्षा संघर्ष

मेटाडाटा एसएसओसीआईआरकल पर कॉन्फ़िगर किया गया है और http://localhost:8080/myapp तक पहुंचने का प्रयास एसएसओसीआईआरकल पर लॉगिन पेज पर निर्देशित करता है। प्रमाणीकरण के बाद, ब्राउज़र http://localhost:8080/myapp/saml/SSO पर रीडायरेक्ट और एक त्रुटि उत्पन्न करता है:

HTTP स्थिति 403 - अपेक्षित CSRF टोकन नहीं मिला। क्या आपका सत्र समाप्त हो गया है?

अगर हम सीएसआरएफ सुरक्षा बंद कर देते हैं, तो सबकुछ काम करता है। हम सीएसआरएफ सुरक्षा को कैसे बनाए रख सकते हैं और अभी भी एसएएमएल एक्सटेंशन का उपयोग कर सकते हैं?

SAML एक्सटेंशन सेट अप करने से पहले, हमने एक लॉगिन फॉर्म और सीएसआरएफ सुरक्षा का उपयोग किया और हमें लॉगिन जेएसपी पर कोई त्रुटि नहीं मिली और इसमें टोकन नहीं था।

SAML से पहले कोड:

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"); 
} 

कोड:

@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("/"); 
} 

अद्यतन

CSRF संरक्षण को पुन: सक्षम और डिबग करने के लिए लॉग इन करने करने के बाद, यहां लॉग हैं कि सफल प्रमाणीकरण के बाद सही होता है:

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: [email protected] 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.se[email protected]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 

उत्तर

8

आपके पास कम से कम दो विकल्प हैं।

http.csrf().requireCsrfProtectionMatcher(matcher); 

अन्य, आसान एक में स्प्रिंग SAML अंतिम बिंदुओं को परिभाषित करने के लिए है:

एक एक कस्टम RequestMatcher (org.springframework.security.web.util.RequestMatcher) जो वसंत SAML यूआरएल पर से मेल नहीं खाएगी और साथ CSRF विन्यास को यह प्रदान लागू करने के लिए है अलग http कॉन्फ़िगरेशन जिसमें csrf सुरक्षा सक्षम नहीं होगी।

एक्सएमएल विन्यास करने के लिए इस के समान हो सकता है:

<!-- SAML processing endpoints --> 
<security:http pattern="/saml/**" entry-point-ref="samlEntryPoint"> 
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/> 
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/> 
</security:http> 

<!-- Secured pages with SAML as entry point --> 
<security:http entry-point-ref="samlEntryPoint"> 
    <security:csrf /> 
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/> 
    <security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/> 
</security:http> 

इस तरह जावा विन्यास कुछ काम करना चाहिए के लिए:

@Configuration 
@EnableWebSecurity 
public class MutlipleHttpConfigurationConfig { 

    @Configuration 
    @Order(1) 
    public static class SAMLWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 
     protected void configure(HttpSecurity http) throws Exception { 
      http.antMatcher("/saml/**"); 
      http.csrf().disable(); 
      http.httpBasic().authenticationEntryPoint(samlEntryPoint()); 
      http.addFilterBefore(metadataGeneratorFilter(), 
        ChannelProcessingFilter.class).addFilterAfter(samlFilter(), 
        BasicAuthenticationFilter.class); 
     } 
    } 

    @Configuration 
    public static class BasicWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 
     protected void configure(HttpSecurity http) throws Exception { 
      http.httpBasic().authenticationEntryPoint(samlEntryPoint()); 
      http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class); 
      http 
        .authorizeRequests() 
        .antMatchers("/error").permitAll() 
        .anyRequest() 
        .hasAnyAuthority("MyRole") 
        .anyRequest().authenticated(); 

      http.logout().logoutSuccessUrl("/"); 
     } 
    } 
} 
जावा विन्यास के साथ कई http विन्यास को परिभाषित करने पर

विवरण पाया जा सकता है Spring Security manual में।

4

अन्य लोगों के लिए जो इस समस्या का सामना कर सकते हैं, मैं फ़िल्टर के आदेश को मजबूर कर इसे हल करने में भी सक्षम था।

http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class) 
    .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class); 
इस के साथ

:

मैं इस प्रतिस्थापित

FilterChainProxy samlFilter = samlFilter(); 

http.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class) 
    .addFilterAfter(samlFilter, BasicAuthenticationFilter.class) 
    .addFilterBefore(samlFilter, CsrfFilter.class); 

और अब यह काम करता है।

+1

आप मेरा दिन बचाया: जब /saml/**

से प्रसंस्करण

http.csrf().ignoringAntMatchers("/saml/**") ...

तो CSRF अक्षम किया गया है! धन्यवाद। – Evgeni

संबंधित मुद्दे