[spring] 요청 매개 변수 ‘_csrf’또는 헤더 ‘X-CSRF-TOKEN’에서 유효하지 않은 CSRF 토큰 ‘null’이 발견되었습니다.

Spring Security 3.2를 구성한 후 _csrf.token요청 또는 세션 개체에 바인딩되지 않습니다.

이것은 스프링 보안 구성입니다.

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

UPDATE
약간의 디버그 후 요청 객체는 DelegatingFilterProxy 형식으로 잘 나오지만 CoyoteAdapter의 469 행에서 request.recycle (); 모든 속성을 지우는 …

Tomcat 6.0.36, 7.0.50에서 JDK 1.7로 테스트합니다.

이 동작을 이해하지 못했습니다. 누군가가 CSRF와 함께 작동하는 Spring Security 3.2와의 일부 애플리케이션 샘플 전쟁의 방향을 제시한다면 가능할 것입니다.



답변

Spring 애플리케이션에서 CSRF (Cross Site Request Forgery) 보호가 활성화 된 것 같습니다. 실제로 기본적으로 활성화되어 있습니다.

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


답변

로그인 양식에 추가해야하지 않습니까?;

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

여기 Spring 보안 문서에 명시된 바와 같이


답변

신청하면 security="none"csrf 토큰이 생성되지 않습니다. 페이지는 보안 필터를 통과하지 않습니다. 역할 익명을 사용하십시오.

나는 자세히 설명하지 않았지만 그것은 나를 위해 일하고 있습니다.

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


답변

이것을 다음으로 변경 <csrf /> 하십시오 : <csrf disabled="true"/>. csfr을 비활성화해야합니다.


답변

thymeleaf를 사용하면 다음을 추가 할 수 있습니다.

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


답변

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


답변

나는 같은 문제가 있었다.

구성은 security = “none”을 사용하므로 _csrf를 생성 할 수 없습니다.

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

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