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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36261781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:10:20  来源:igfitidea点击:

X-CSRF-TOKEN is not generated by Spring Booot

javaspringspring-securityspring-bootcsrf

提问by Bruno Vignola

I followed the guide here: http://spring.io/guides/gs/rest-service/to build my rest service example and now I am trying to enable the CSRF protection. I read that it should be enabled by default, so if I DON'T include:

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

http.csrf().disable()

http.csrf().disable()

in my WebSecurityConfigurerAdapterconfiguration, the CSRF protectection should be enabled by default, but it does not seem to to be the case. The problem is that the X-CSRF-TOKEN is not generated and not included in my HTTP response in any way. What am I expected to do, to have the x-csrf-token generated and included in the response and, of course, the csrf protection fully working?

在我的WebSecurityConfigurerAdapter配置中,CSRF 保护应该默认启用,但似乎并非如此。问题是 X-CSRF-TOKEN 没有生成,也没有以任何方式包含在我的 HTTP 响应中。我应该怎么做,让 x-csrf-token 生成并包含在响应中,当然还有 csrf 保护完全起作用?

I noticed that, with a similar spring mvc configuration, I get the x-csrf-token generated simply including:

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

< security:csrf disabled="false"/>

< security:csrf disabled="false"/>

in my security configuration file. But, with spring boot maybe I am getting something wrong and there is no way to have the csrf token generated. Can anybody help me, perhaps pointing me to a working example? My security configuration is:

在我的安全配置文件中。但是,使用 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);
}

回答by jeadonara

To include the CSRF Token in your csrf protection, you can include CSRFTokenRepository to generate tokens. To illustrate in your case adding a simple line is enough:

要在您的 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());}
 @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());}

回答by Melvin Sy

Using Spring security 5.3.0.Final, one of the ways you can generate the CSRFtoken is by setting in the cookie by using the following code below.

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

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

You also need to include the generated CSRF token in your request for the server to authorize.

您还需要在请求服务器授权时包含生成的 CSRF 令牌。

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

In the event you're using a JS framework, you need to include the token by setting it in the request header.

如果您使用的是 JS 框架,则需要通过在请求标头中设置令牌来包含令牌。

Here is an example for a JQuery ajax call.

这是 JQuery ajax 调用的示例。

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

There are other implementations that will suit your needs that are documented here by Spring. https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf

Spring 在此处记录了其他满足您需求的实现。https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf

回答by Türkmen Mustafa Demirci

We had pretty similar issue during our security tests where we suspected that we accidentally disable csfr in configure method of websecurityconfig class,by default it is enabled. by changing the congfigure method as shown below , we had spring automatically generate csfr tokens.

我们在安全测试中遇到了非常相似的问题,我们怀疑我们不小心在 websecurityconfig 类的配置方法中禁用了 csfr,默认情况下它是启用的。通过如下所示更改配置方法,我们让 spring 自动生成 csfr 令牌。

websecurityconfig class configure method==>

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