春季 4 和 CSRF

Posted

技术标签:

【中文标题】春季 4 和 CSRF【英文标题】:spring 4 and CSRF 【发布时间】:2016-01-04 02:13:17 【问题描述】:

我在单页应用程序中使用 spring boot、spring rest 和 spring security。

在 spring 4 中,CSRF 默认是启用的。

我写了一个扩展WebSecurityConfigureAdapter的类

    protected void configure(HttpSecurity http) throws Exception 
      http.authorizeRequests().antMatchers("/rest/**").authenticated();

      http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
      http.formLogin().successHandler(authenticationSuccessHandler);
      http.formLogin().failureHandler(authenticationFailureHandler);
      http.logout().logoutSuccessUrl("/");

    // tried with and without... same issue
      http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);


CsrfTokenResponseHeaderBindingFilter 来自 https://github.com/aditzel/spring-security-csrf-filter/blob/master/src/main/java/com/allanditzel/springframework/security/web/csrf/CsrfTokenResponseHeaderBindingFilter.java

我只使用 html(所以没有 jsp,没有 xhmtl...)页面。 我做 ajax 调用并提供我的 html。

请求头

POST /login HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 30
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Origin: http://localhost:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=B05ED2676EC1637D74AC7622E018C9FD

在我的表单中

 <input type="hidden" name="$_csrf.parameterName" value="$_csrf.token"/>

当我尝试登录时,我得到了

"timestamp":1444179957867,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/login"

日志失败时,该命令返回null

jqXHR.getResponseHeader('X-CSRF-TOKEN')

ajax 调用

var data = 'username=' + $('#username').val() + '&password=' +  $('#password').val();
  $.ajax(
    data: data,
    timeout: 1000,
    type: 'POST',
    url: '/login'
  ).done(function (data, textStatus, jqXHR) 
     window.location = "main.html";
  ).fail(function (jqXHR, textStatus, errorThrown) 
  );
);

编辑

当我连接到 localhost:8080 时在浏览器中。

我在标题答案中看到

X-CSRF-HEADER:X-CSRF-TOKEN
X-CSRF-PARAM:_csrf
X-CSRF-TOKEN:0d5bf042-a30f-4f2e-a99c-51ed512f811a

如何在 JS 中获取这些信息?我需要把它放在我的 post call 中。

【问题讨论】:

请向我们展示 HTTP 请求 您没有在帖子中发送 csrf 参数 我想放什么? 【参考方案1】:

没有足够的信息来调试此问题。您应该发布以下信息:

    您的 XML/Java Spring 安全配置。 您的 Spring Web 配置。您使用的是 JSP 还是 XHTML?你确定你的视图模型是正确的吗?也许您遇到的问题是 Web 模块未发送令牌。 实际的 http 请求标头/正文。请求实际上是正确的还是 spring 只是没有获取令牌?

【讨论】:

以上是关于春季 4 和 CSRF的主要内容,如果未能解决你的问题,请参考以下文章

java 春季4+特别交易

从春季启动以角度4发布上传文件?

春季批处理:如果作业在最后 xx 分钟内失败,则向 grafana 和 prometheus 发出警报

2018年春季个人阅读计划

西南民族大学 春季 2023 训练赛4

春季注销时出现错误 404