【问题标题】:In Spring-Security with Java Config, why does httpBasic POST want csrf token?在带有 Java Config 的 Spring-Security 中,为什么 httpBasic POST 需要 csrf 令牌?
【发布时间】:2014-01-03 08:13:51
【问题描述】:

我正在使用带有 Java 配置的 Spring-Security 3.2.0.RC2。 我设置了一个简单的 HttpSecurity 配置,要求在 /v1/** 上进行基本身份验证。 GET 请求有效,但 POST 请求失败:

HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

我的安全配置如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Resource
private MyUserDetailsService userDetailsService;

@Autowired
//public void configureGlobal(AuthenticationManagerBuilder auth)
public void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    StandardPasswordEncoder encoder = new StandardPasswordEncoder(); 
    auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}

@Configuration
@Order(1)
public static class RestSecurityConfig
        extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/v1/**").authorizeRequests()
                .antMatchers("/v1/**").authenticated()
            .and().httpBasic();
    }
}

}

非常感谢您对此的任何帮助。

【问题讨论】:

  • 如果您不想禁用 csrf(因为它是有原因的),您可以添加一个带有 csrf-value 的隐藏字段,并添加 starmandeluxe 在接受的帖子中建议的值。这对我来说很好,没有禁用 csrf
  • @Xtroce 是对的,但在我的情况下,我必须将 X-CSRF-TOKEN 添加到 ajax 帖子 headers 中。 (将 _csrf 添加到 ajax 帖子 parameters 不起作用。)
  • 添加到@Xtroce 评论,如果你使用百里香做模板,你可以添加
    和模板引擎将自动提供一个名为“_csrf”的隐藏输入字段,其中填充了正确的值。

标签: post spring-security csrf basic-authentication spring-java-config


【解决方案1】:

CSRF 保护在 Java 配置中默认启用。要禁用它:

@Configuration
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            ...;
    }
}

【讨论】:

  • 那么,显而易见的问题是,如果他没有禁用它,那么他的 null 值有什么问题?我实际上遇到了同样的问题,据我所知,我并没有禁用 CSRF 保护。
  • @starmandeluxe 启用 CSRF 保护后,Spring Security 在使用 POST 时需要来自客户端的 CSRF 令牌。如果客户端不发送这样的token,则为null,即丢失。
  • 哦,但是我正在发送我的 AJAX 调用: beforeSend: function(xhr) { xhr.setRequestHeader('X-CSRF-Token', $("meta[name='_csrf']" ).attr('content'));
  • @starmandeluxe 很难说这么少的信息有什么问题。真的不同的问题; OP 询问的是 REST 服务,您关心的是 AJAX。
  • 很公平,但我的问题并不在于 AJAX。应该由 Spring Security 解析为实际令牌的“${_csrf.token}”没有被转换为令牌。我在这里提出了一个单独的问题:stackoverflow.com/questions/23669424/…
【解决方案2】:

您还可以仅对某些请求或方法禁用 CSRF 检查,对 http 对象使用如下配置:

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

    private Pattern allowedMethods = 
      Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");

    private RegexRequestMatcher apiMatcher = 
      new RegexRequestMatcher("/v[0-9]*/.*", null);

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

        // CSRF disabled on api calls
        if(apiMatcher.matches(request))
            return false;

        // CSRF enables for other requests
        return true;
    }
});

你可以在这里看到更多:

http://blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/

【讨论】:

    猜你喜欢
    • 2015-05-10
    • 2014-12-06
    • 2019-12-30
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 2016-05-02
    • 2015-12-01
    • 2012-03-06
    相关资源
    最近更新 更多