启用S​​pring启动时无法获得csrf保护

时间:2016-03-28 11:54:16

标签: java spring spring-security spring-boot csrf

大家早上好。我是春季启动的新手,我按照指南这里:http://spring.io/guides/gs/rest-service/来构建我的休息服务示例,现在我正在尝试启用CSRF保护。我读过它应该默认启用,所以如果我不包括:

  

http.csrf()。禁用()

在我的WebSecurityConfigurerAdapter配置中,csrf protectection应该是enableb,但似乎并非如此。问题是X-CSRF-TOKEN没有生成,也没有以任何方式包含在我的HTTP响应中。 我希望做什么,生成并包含在响应中的x-csrf-token,当然还有csrf保护完全正常工作?

我注意到,使用类似的spring mvc配置,我得到的x-csrf-token只包括:

  

<安全性:csrf disabled =“false”/>

在我的安全配置文件中。但是,使用spring boot可能会出错,并且无法生成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);
}
非常感谢你。

3 个答案:

答案 0 :(得分:2)

使用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

答案 1 :(得分:0)

我们在安全测试期间遇到了类似的问题,我们怀疑我们在websecurityconfig类的configure方法中意外禁用了csfr,默认情况下已启用。通过改变如下所示的congfigure方法,我们有spring自动生成csfr标记。

websecurityconfig类配置方法==&gt;

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

答案 2 :(得分:0)

要将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());}