spring 在请求参数“_csrf”或标头“X-CSRF-TOKEN”中发现无效的 CSRF 令牌“null”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21128058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:27:27  来源:igfitidea点击:

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

springspring-securitycsrfcsrf-protection

提问by Hugo Robayo

After configuring Spring Security 3.2, _csrf.tokenis not bound to a request or a session object.

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

This is the spring security config:

这是弹簧安全配置:

<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>

The login.jsp file

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>

And it renders the next html:

它呈现下一个 html:

<input type="hidden" name="" value="" />

The result is 403 HTTP status:

结果是 403 HTTP 状态:

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

UPDATEAfter some debug, the request object gets out fine form DelegatingFilterProxy, but in the line 469 of CoyoteAdapter it executes request.recycle(); that erases all the attributes...

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

I test in Tomcat 6.0.36, 7.0.50 with JDK 1.7.

我使用 JDK 1.7 在 Tomcat 6.0.36、7.0.50 中进行测试。

I have not understood this behavior, rather than, it would be possible if someone point me in the direction of some application sample war with Spring Security 3.2 that works with CSRF.

我还没有理解这种行为,而不是,如果有人指出我与与 CSRF 一起工作的 Spring Security 3.2 的某些应用程序示例War的方向,那将是可能的。

回答by MaVRoSCy

It looks like the CSRF (Cross Site Request Forgery) protection in your Spring application is enabled. Actually it is enabled by default.

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

According to spring.io:

根据spring.io

When should you use CSRF protection? Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.

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

So to disable it:

所以要禁用它:

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

If you want though to keep CSRF protection enabled then you have to include in your form the csrftoken. You can do it like this:

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

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

You can even include the CSRF token in the form's action:

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

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

回答by borjab

Shouldn't you add to the login form?;

你不应该添加到登录表单吗?

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

As stated in the herein the Spring security documentation

如Spring 安全文档中的此处所述

回答by Awanish Kumar

If you will apply security="none"then no csrf token will be generated. The page will not pass through security filter. Use role ANONYMOUS.

如果您申请,security="none"则不会生成 csrf 令牌。该页面不会通过安全过滤器。使用角色匿名。

I have not gone in details, but it is working for me.

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

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

回答by Arkadiusz Gibes

Try to change this: <csrf />to this : <csrf disabled="true"/>. It should disable csfr.

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

回答by Lay Leangsros

With thymeleaf you may add:

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

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

回答by Rahul Raj

Spring documentation to disable csrf: https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-configure

禁用 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();
   }
}

回答by xxg

I used to have the same problem.

我曾经有同样的问题。

Your config use security="none" so cannot generate _csrf:

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

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

you can set access="IS_AUTHENTICATED_ANONYMOUSLY" for page /login.jsp replace above config:

您可以设置 access="IS_AUTHENTICATED_ANONYMOUSLY" 页面 /login.jsp 替换上面的配置:

<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>

回答by Saurabh Kumar

i think csrf only works with spring forms

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

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

change to form:formtag and see it that works.

更改为form:form标记并查看它是否有效。

回答by manish

Please see my working sample application on Githuband compare with your set up.

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

回答by vancho

Neither one of the solutions worked form me. The only one that worked for me in Spring form is:

没有一种解决方案对我有用。在 Spring 形式中唯一对我有用的是:

action="./upload?${_csrf.parameterName}=${_csrf.token}"

action="./upload? ${_csrf.parameterName}=${_csrf.token}"

REPLACED WITH:

替换为:

action="./upload?_csrf=${_csrf.token}"

action="./upload? _csrf=${_csrf.token}"

(Spring 5 with enabled csrf in java configuration)

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