配置Spring Security 3.2之后,_csrf.token未绑定(bind)到请求或 session 对象。

这是spring安全配置:

<http pattern="/login.jsp" security="none"/>

<http>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <form-login login-page="/login.jsp"
                authentication-failure-url="/login.jsp?error=1"
                default-target-url="/index.jsp"/>
    <logout/>
    <csrf />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="test" password="test" authorities="ROLE_USER/>
        </user-service>
    </authentication-provider>
</authentication-manager>

login.jsp文件
<form name="f" action="${contextPath}/j_spring_security_check" method="post" >
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    <button id="ingresarButton"
            name="submit"
            type="submit"
            class="right"
            style="margin-right: 10px;">Ingresar</button>
    <span>
        <label for="usuario">Usuario :</label>
        <input type="text" name="j_username" id="u" class="" value=''/>
    </span>
    <span>
        <label for="clave">Contrase&ntilde;a :</label>

        <input type="password"
               name="j_password"
               id="p"
               class=""
               onfocus="vc_psfocus = 1;"
               value="">
    </span>
</form>

并呈现下一个html:
<input type="hidden" name="" value="" />

结果是403 HTTP状态:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

更新
在进行一些调试之后,请求对象会脱离DelegatingFilterProxy的形式,但是在CoyoteAdapter的469行中,它执行request.recycle();。删除所有属性...

我在JDK 1.7的Tomcat 6.0.36、7.0.50中进行了测试。

我还不了解这种行为,相反,如果有人指出我对与CSRF一起使用的Spring Security 3.2进行一些应用程序示例 war 的方向是可能的。

最佳答案

看起来您的Spring应用程序中的CSRF(跨站点请求伪造)保护已启用。实际上,默认情况下它是启用的。

根据spring.io:



所以要禁用它:

@Configuration
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
  }
}

如果您想保持CSRF保护状态,则必须在表单中加入csrftoken。您可以这样做:
<form .... >
  ....other fields here....
  <input type="hidden"  name="${_csrf.parameterName}"   value="${_csrf.token}"/>
</form>

您甚至可以在表单的操作中包含CSRF token :
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">

07-24 19:59
查看更多