在请求参数'_csrf'或标题'X-CSRF-TOKEN'上找到无效的CSRF令牌'null'

Hug*_*ayo 88 spring csrf spring-security csrf-protection

配置Spring Security 3.2后,_csrf.token不会绑定请求或会话对象.

这是spring security配置:

<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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

它呈现下一个HTML:

<input type="hidden" name="" value="" />
Run Code Online (Sandbox Code Playgroud)

结果是403 HTTP状态:

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
Run Code Online (Sandbox Code Playgroud)

更新 在一些调试之后,请求对象从DelegatingFilterProxy中获得良好的形式,但是在CoyoteAdapter的第469行中它执行request.recycle(); 删除所有属性......

我使用JDK 1.7在Tomcat 6.0.36,7.0.50中进行测试.

我没有理解这种行为,而不是,如果有人指出我使用与CSRF一起工作的Spring Security 3.2的应用程序样本战争的方向,那么这是可能的.

MaV*_*SCy 97

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

根据spring.io:

什么时候应该使用CSRF保护?我们的建议是对普通用户可以由浏览器处理的任何请求使用CSRF保护.如果您只创建非浏览器客户端使用的服务,则可能需要禁用CSRF保护.

所以要禁用它:

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

如果您希望保持启用CSRF保护,那么您必须在表单中包含csrftoken.你可以这样做:

<form .... >
  ....other fields here....
  <input type="hidden"  name="${_csrf.parameterName}"   value="${_csrf.token}"/>
</form>
Run Code Online (Sandbox Code Playgroud)

您甚至可以在表单的操作中包含CSRF令牌:

<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
Run Code Online (Sandbox Code Playgroud)

  • 这应该被接受为答案,因为它不仅解释了要做什么,还解释了在采取措施阻止这些错误之前应该考虑的事项。 (2认同)

bor*_*jab 31

你不应该加入登录表单吗?

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
Run Code Online (Sandbox Code Playgroud)

正如指出这里的春季安全文档中


Awa*_*mar 12

如果您将应用security ="none",则不会生成csrf令牌.页面不会通过安全筛选器.使用角色ANONYMOUS.

我没有详细介绍,但它对我有用.

 <http auto-config="true" use-expressions="true">
   <intercept-url pattern="/login.jsp" access="hasRole('ANONYMOUS')" />
   <!-- you configuration -->
   </http>
Run Code Online (Sandbox Code Playgroud)


小智 7

试着改变这个:<csrf /> 对此:<csrf disabled="true"/>.它应该禁用csfr.


Lay*_*ros 7

使用百里香叶,您可以添加:

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
Run Code Online (Sandbox Code Playgroud)


小智 6

用于禁用csrf的Spring文档:https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-configure

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
      http.csrf().disable();
   }
}
Run Code Online (Sandbox Code Playgroud)


man*_*ish 1

请参阅我在 Github 上的工作示例应用程序并与您的设置进行比较。