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

时间:2014-01-15 02:27:30

标签: spring spring-security csrf 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>

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的应用程序示例战争的方向,那么就有可能。

12 个答案:

答案 0 :(得分:91)

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

根据spring.io

  

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

所以要禁用它:

@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令牌:

<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">

答案 1 :(得分:28)

您是否应该添加到登录表单?;

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

如Spring安全文档中的here所述

答案 2 :(得分:12)

如果您将申请安全=&#34;无&#34;那么就不会生成csrf令牌。页面不会通过安全筛选器。使用角色ANONYMOUS。

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

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

答案 3 :(得分:7)

尝试将此更改为<csrf /><csrf disabled="true"/>。它应该禁用csfr。

答案 4 :(得分:6)

有了百里香,你可以补充一下:

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>

答案 5 :(得分: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();
   }
}

答案 6 :(得分:4)

我曾经遇到同样的问题。

您的配置使用security =“none”,因此无法生成_csrf:

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

你可以为page /login.jsp设置access =“IS_AUTHENTICATED_ANONYMOUSLY”替换上面的配置:

<http>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <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>

答案 7 :(得分:2)

我认为csrf仅适用于弹簧形式

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

更改为form:form代码并查看其有效。

答案 8 :(得分:1)

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

答案 9 :(得分:1)

其中一个解决方案都不适用于我。 Spring中唯一能为我工作的是:

行动= “./上传?的 $ {_ csrf.parameterName} = $ {_ csrf.token}”

替换为:

行动= “./上传?的 _csrf = $ {_ csrf.token}”

(Spring 5,在java配置中启用了csrf)

答案 10 :(得分:0)

在您的控制器中添加以下内容:

@RequestParam(value = "_csrf", required = false) String csrf

在jsp页面上添加

<form:form modelAttribute="someName" action="someURI?${_csrf.parameterName}=${_csrf.token}

答案 11 :(得分:-1)

我使用Spring 4.2.3版本jar来保证弹簧安全,但是我得到了同样的错误。然后我降级到3.1.4,这完美无缺。

以下是我对pom.xml的依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.26</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate</artifactId>
    <version>3.5.4-Final</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.1.Final</version>
</dependency>
<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.4.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>3.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>3.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.1.4.RELEASE</version>
</dependency>