簡體   English   中英

X-CSRF-TOKEN 不是由 Spring Boot 生成的

[英]X-CSRF-TOKEN is not generated by Spring Boot

我按照此處的指南: http://spring.io/guides/gs/rest-service/構建我的 rest 服務示例,現在我正在嘗試啟用 CSRF 保護。 我讀到它應該默認啟用,所以如果我不包括:

http.csrf().disable()

在我的WebSecurityConfigurerAdapter配置中,默認情況下應該啟用 CSRF 保護,但似乎並非如此。 問題是 X-CSRF-TOKEN 沒有生成,也沒有以任何方式包含在我的 HTTP 響應中。 我應該做什么,才能生成 x-csrf-token 並將其包含在響應中,當然,csrf 保護也能充分發揮作用?

我注意到,使用類似的 spring mvc 配置,我得到了生成的 x-csrf-token,其中僅包括:

<安全:csrf禁用=“假”/>

在我的安全配置文件中。 但是,使用 spring 啟動時,我可能會出錯,並且無法生成 csrf 令牌。 任何人都可以幫助我,也許可以指出一個可行的例子嗎? 我的安全配置是:

     @Override
     protected void configure(HttpSecurity http) throws Exception 
     {
        http
      // .csrf().disable()
      .authorizeRequests()
          .anyRequest()
          .authenticated()
      .and()
      .httpBasic()
      .authenticationEntryPoint(new RestAuthenticationEntryPoint())
      .and()
      .formLogin()
      .successHandler(new RestAuthenticationSuccessHandler())
      .failureHandler(new SimpleUrlAuthenticationFailureHandler())
      .and()
      .logout()
      .logoutSuccessHandler(new RestLogoutSuccessHandler());
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception 
{
    auth.userDetailsService(restUserDetailService);
}

要在您的 csrf 保護中包含 CSRF 令牌,您可以包含 CSRFTokenRepository 以生成令牌。 為了說明您的情況,添加一條簡單的行就足夠了:

 @Override protected void configure(HttpSecurity http) throws Exception { http. .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //HERE ! Defaults XSRF-TOKEN as cookie name and X-XSRF-TOKEN as header name .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic() .authenticationEntryPoint(new RestAuthenticationEntryPoint()) .and() .formLogin() .successHandler(new RestAuthenticationSuccessHandler()) .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout() .logoutSuccessHandler(new RestLogoutSuccessHandler());}

使用 Spring security 5.3.0.Final,生成CSRF令牌的方法之一是使用以下代碼在 cookie 中進行設置。

 http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))

您還需要在請求服務器授權時包含生成的 CSRF 令牌。

<form>
    <input type="hidden" name="_csrf" value="${cookie['XSRF-TOKEN'].getValue()}" />
    //Code goes here
</form>

如果您使用的是 JS 框架,則需要通過在請求標頭中設置令牌來包含令牌。

這是 JQuery ajax 調用的示例。

// Get the CSRF token from the cookie
const csrfCookie= document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1');
// Add the CSRF token to each ajax request header
settings.beforeSend = function(xhr) {
  xhr.setRequestHeader('X-XSRF-TOKEN', springCsrfCookie);
};
$.ajax(settings);

Spring 在此處記錄了其他滿足您需求的實現。 https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf

您可以配置CookieCsrfTokenRepository 使用 Java 配置將 CSRF 令牌存儲在 Cookie 中

    @Override
    protected void configure(HttpSecurity http) {
        http
            .csrf(csrf ->
                csrf
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            );
    }

我們在安全測試期間遇到了非常相似的問題,我們懷疑我們不小心在 websecurityconfig 類的配置方法中禁用了 csfr,默認情況下它是啟用的。 通過如下所示更改配置方法,我們讓 spring 自動生成 csfr 令牌。

websecurityconfig 類配置方法==>

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

     http
     .authorizeRequests()
         .antMatchers("/", "/login","/loginError","/home","/interruption").permitAll()                                                          
         .antMatchers("/admin").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.HALLEYYNT01.role())  
         .antMatchers("/requests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.CCHALLEYLOGIN.role())
         .antMatchers("/solrequests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.SOLHALLEYLOGIN.role())
         .anyRequest().authenticated()
         .and()
     .formLogin()             
         .loginPage("/login")  
         //.failureUrl("/loginError")
         .loginProcessingUrl("/authenticate")
         .defaultSuccessUrl("/")            
         .and()
     .logout().clearAuthentication(true).invalidateHttpSession(true).deleteCookies("JSESSIONID")         
         .logoutSuccessUrl("/login");
         //.and() 
     //.exceptionHandling().accessDeniedHandler(accessDeniedHandler);    
}   

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM