Подтвердить что ты не робот

Ожидаемый токен CSRF не найден. Срок действия вашей сессии 403

Я пытаюсь написать свое тестовое приложение безопасности spring с примерами 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.

Что не так, как я могу это исправить? Я прокомментировал csrf в конфиге, но сообщение об ошибке связано с csrf.

4b9b3361

Ответ 1

У меня была та же проблема. Я использую thymeleaf и Spring boot, и получил проблему с токеном CSRF, когда я пытаюсь отправить данные в форме.

Вот мое рабочее решение:

  • Добавьте этот скрытый ввод:

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

  • В WebSecurityConfig (который продолжается WebSecurityConfigurerAdapter) добавьте метод:

    private CsrfTokenRepository csrfTokenRepository() 
    { 
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
        repository.setSessionAttributeName("_csrf");
        return repository; 
    }
    

    и добавьте код в метод configure():

    @Override
     protected void configure(HttpSecurity http) throws Exception {
         http.csrf()
         .csrfTokenRepository(csrfTokenRepository())
    

Я потратил много времени на эту проблему. Надеюсь, что это поможет кому-то, у кого такая же проблема.

Ответ 2

Если вы должны отключить его...

В Spring Безопасность 4, CSRF включен по умолчанию при использовании конфигурации XML. Раньше он был включен по умолчанию для конфигурации на основе Java.

Согласно Раздел 14.4.2 Spring Документация по безопасности:

Как и в случае с Spring Security 4.0, защита CSRF по умолчанию включена с конфигурацией XML. Если вы хотите отключить защиту CSRF, соответствующую конфигурацию XML можно увидеть ниже.

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

Ответ 3

Отключение защиты CSRF звучит как плохая идея, нет?

Если вы используете библиотеку тегов Spring, токен CSRF будет автоматически включен. Он также будет содержать значения элементов HTML Escape, что сделает ваш сайт более безопасным с 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

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

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>

web.xml

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

добавить добавить jsp login

<%@page session="true"%>

и ввод скрыт:

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