복붙노트

[SPRING] 예상 CSRF 토큰을 찾을 수 없습니다. 세션이 만료되었습니다. 403

SPRING

예상 CSRF 토큰을 찾을 수 없습니다. 세션이 만료되었습니다. 403

mkyong 예제를 사용하여 테스트 용 스프링 보안 애플리케이션을 작성하려고합니다.

Spring Security: 4.0.0.RC1
Spring: 4.1.4.RELEASE

다음과 같은 보안 구성이 있습니다.

<http auto-config="true">
    <intercept-url pattern="/admin**" 
                    access="hasRole('ADMIN')"/>
    <form-login authentication-failure-url="/?auth_error" 
                        username-parameter="user" 
                        password-parameter="password" 
                        login-page="/"
                        default-target-url="/?OK"/>
<!-- <csrf/> -->
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="mkyong" password="123456" authorities="ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

로그인 페이지:

<html>
<body>
<form method="POST">
    <label for="user">User: </label>
    <input type="text" id="user" name="user" /> </br>
    <label for="password">Password: </label>
    <input type="text" name="password" id="password" /> </br>
    <input type="submit" /> 
</form>
</body>
</html>

이제 로그인을 시도하면 403 오류 페이지가 표시됩니다.

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

기술:

Access to the specified resource (Invalid CSRF Token 'null' was
found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.) has been 
forbidden.

뭐가 잘못 됐어, 어떻게 해결할 수 있니? 나는 config에서 csrf를 주석 처리했지만 오류 메시지는 csrf와 관련이 있습니다.

해결법

  1. ==============================

    1.나는 똑같은 문제가 있었다. 나는 thymeleaf와 Spring boot를 사용하고 폼에 데이터를 게시하려고 할 때 CSRF 토큰 문제를 가지고있다.

    나는 똑같은 문제가 있었다. 나는 thymeleaf와 Spring boot를 사용하고 폼에 데이터를 게시하려고 할 때 CSRF 토큰 문제를 가지고있다.

    다음은 제 작업 솔루션입니다.

    나는이 문제에 많은 시간을 보냈다. 같은 문제가있는 사람을 도울 수 있기를 바랍니다.

  2. ==============================

    2.사용을 중지해야하는 경우 ...

    사용을 중지해야하는 경우 ...

    스프링 시큐리티 4에서 CSRF는 XML 설정을 사용할 때 기본적으로 사용 가능합니다. 이전에는 Java 기반 구성에서만 기본적으로 활성화되었습니다.

    스프링 보안 문서의 섹션 14.4.2에 따르면 :

    <http>
       ...
       <csrf disabled="true"/>
       ...
    </http>
    
  3. ==============================

    3.CSRF 보호 기능을 해제하는 것은 좋지 않은 생각처럼 들리지만 그렇지 않습니다.

    CSRF 보호 기능을 해제하는 것은 좋지 않은 생각처럼 들리지만 그렇지 않습니다.

    Spring의 양식 태그 라이브러리를 사용하면 CSRF 토큰이 자동으로 포함됩니다. 또한 HTML 이스케이프 양식 요소 값을 사용하여 사이트를 XSS에 대해보다 안전하고 정확하게 만듭니다.

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

    그렇지 않으면 양식에 다음을 추가하십시오.

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

    4.@ St.Antario하려면,   이 코드를 사용하여 코드에서 CSRF를 활성화하십시오.

    @ St.Antario하려면,   이 코드를 사용하여 코드에서 CSRF를 활성화하십시오.

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("*/*").authorizeRequests()
                    .antMatchers("/", "/login**").permitAll()
                    .anyRequest().authenticated()
                    .and().csrf().csrfTokenRepository(csrfTokenRepository())
                    .and().addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
        }
    
        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
    
                @Override
                protected void doFilterInternal(HttpServletRequest request,
                                                HttpServletResponse response,
                                                FilterChain filterChain) throws ServletException, IOException {
    
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null
                                && !token.equals(cookie.getValue())) {
    
                            // Token is being added to the XSRF-TOKEN cookie.
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }
    
        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            //repository.setSessionAttributeName(("X-XSRF-TOKEN"));
            return repository;
        }
    }
    
  5. ==============================

    5.spring-security.xml

    spring-security.xml

    <beans:beans xmlns="http://www.springframework.org/schema/security"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:beans="http://www.springframework.org/schema/beans"
                 xsi:schemaLocation="
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <http pattern="/resources/**" security="none" />
    
        <http use-expressions="true">
            <intercept-url pattern="/login*" access="isAnonymous()" />
            <intercept-url pattern="/**" access="isAuthenticated()"/>
            <form-login
                login-page="/login"
                default-target-url="/home"
                authentication-failure-url="/login?error=true" /> 
            <logout
                logout-success-url="/login"
                delete-cookies="JSESSIONID" />
        </http>
        <authentication-manager>
            <authentication-provider>
                <user-service>
                    <user name="carlos" password="123" authorities="ROLE_USER" />
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </beans:beans>
    

    을 포함한다.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml, /WEB-INF/spring-security.xml</param-value>
    </context-param>
    

    add jsp login을 추가하십시오

    <%@page session="true"%>
    

    숨겨진 입력 :

    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    
  6. from https://stackoverflow.com/questions/28138864/expected-csrf-token-not-found-has-your-session-expired-403 by cc-by-sa and MIT license