2017-03-12 12 views
1

私は春のセキュリティを使用して春のプロジェクトを作成していますが、私は自分のAPIだけで問題が発生しています(すべてのコントローラがcsrfで正しく動作しています)。しかし、私は私のAPIにリクエストを作るとき私が得るためCSRFは、私のAPIに問題を引き起こしているように思える:¿どのように私は春のセキュリティと私のAPIのためだけにCSRFを無効にすることができますか?

{"id":41,"titulo":"vineta3","creationdate":1489421003000,"URL":"http://i2.kym-cdn.com/photos/images/facebook/000/125/918/RMUBQ.png","likes":0,"dislikes":0,"descripcion":"des3"}{"timestamp":1489421218765,"status":200,"error":"OK","exception":"java.lang.IllegalStateException","message":"Cannot create a session after the response has been committed","path":"/api/vineta/41/"} 

最後情報:私のプロジェクトがなかった場合に

{"timestamp":1489421218765,"status":200,"error":"OK","exception":"java.lang.IllegalStateException","message":"Cannot create a session after the response has been committed","path":"/api/vineta/41/"} 

が戻っていません春の秘密。私のセキュリティ設定に次のコードを使用しています。

public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Autowired 
public UserRepositoryAuthenticationProvider authenticationProvider; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    // Public pages 
    http.authorizeRequests().antMatchers("/").permitAll(); 
    http.authorizeRequests().antMatchers("/login").permitAll(); 
    http.authorizeRequests().antMatchers("/loginerror").permitAll(); 
    http.authorizeRequests().antMatchers("/registro").permitAll(); 
    http.authorizeRequests().antMatchers("/signup").permitAll(); 
    http.authorizeRequests().antMatchers(HttpMethod.GET, "/api/**").permitAll();   


    // Private pages (all other pages) 
    http.authorizeRequests().antMatchers("/home").hasAnyRole("USER"); 
    //http.authorizeRequests().antMatchers("/crearComentario/vineta/{id}").hasAnyRole("USER"); 

    // Login form 
    http.formLogin().loginPage("/login"); 
    http.formLogin().usernameParameter("username"); 
    http.formLogin().passwordParameter("password"); 
    http.formLogin().defaultSuccessUrl("/home"); 
    http.formLogin().failureUrl("/loginerror"); 

    // Logout 
    http.logout().logoutUrl("/logout"); 
    http.logout().logoutSuccessUrl("/"); 

} 

@Override 
protected void configure(AuthenticationManagerBuilder auth) 
     throws Exception { 
    // Database authentication provider 
    auth.authenticationProvider(authenticationProvider); 
} 

}

と私のCSRFのための次の:コンソールで

@Configuration 
public class CSRFHandlerConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
     registry.addInterceptor(new CSRFHandlerInterceptor()); 
    } 
} 

class CSRFHandlerInterceptor extends HandlerInterceptorAdapter { 

    @Override 
    public void postHandle(final HttpServletRequest request, 
      final HttpServletResponse response, final Object handler, 
      final ModelAndView modelAndView) throws Exception { 

     CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); 
     modelAndView.addObject("token", token.getToken());  
    } 
} 

、私は次のログを見ることができます:

org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25] 
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed 
    at org.apache.catalina.connector.Request.doGetSession(Request.java:2928) ~[tomcat-embed-core-8.0.32.jar:8.0.32] 

イムSingleTransactionsControllerを使用していません、これは問題になる可能性がありますか?

+0

を変更した後、今私は、 {"timestamp":1489421060885、 "status":200、 "error": "OK"、 "exception": "java.lang.IllegalStateException"、 "message": "応答がコミットされた後にセッションを作成できません"、" path ":"/api/usuarios/"} と私のコンソールに表示されます エラー32628 --- [nio-8080-exec-3] oaccC [Tomcat]。[localhost]:例外処理ErrorPage [errorCode = 0、location =/error] org.springframework.web.util.NestedServletException:リクエストの処理に失敗しました。ネストされた例外はjava.lang.IllegalStateExceptionです:応答がコミットされた後にセッションを作成できません – randall

答えて

4

あなたがCSRFHandlerInterceptorを使用する理由私は理解していないが、あなたが唯一のAPIのためCRSFを無効にしたい場合は、私は2つのソリューションを持っている:

  1. を次の例のように、CSRFフィルターにrequireCsrfProtectionMatcherを注入することができます

    http 
        .csrf() 
         .requireCsrfProtectionMatcher(newAndRequestMatcher(CsrfFilter.DEFAULT_CSRF_MATCHER, new RegexRequestMatcher("^(?!/api/)", null))); 
    

    デフォルト・マッチャは、メソッド整合であり、そして第二の整合はない/api/要求のために使用されます。

  2. あなたはCSRFなしAPIのURLをのみ/apiための新しい春のセキュリティ設定を作成し、デフォルトの春のセキュリティの設定の前に順序を設定し、一致させることができます:

    http.requestMatcher(new AntPathRequestMatcher("/api/**")).csrf().disable(); 
    
1

CSRFの設定が春にグローバルでありますセキュリティ

これは助けることができる:

http.csrf().requireCsrfProtectionMatcher(new RequestMatcher() { 

     private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$"); 
     // regex to match your api url 
     private RegexRequestMatcher apiMatcher = new RegexRequestMatcher("/v[0-9]*/.*", null); 

     @Override 
     public boolean matches(HttpServletRequest request) { 
      // No CSRF due to allowedMethod 
      if(allowedMethods.matcher(request.getMethod()).matches()) 
       return false; 

      // No CSRF due to api call 
      if(request.getRequestURI().equals("/view/cpanel/Login.jsp"); 
       return false; 

      // CSRF for everything else that is not an API call or an allowedMethod 
      return true; 
     } 
    }); 
関連する問題