Arhn - архитектура программирования

Spring Security – неверный токен CSRF в /logout

У меня есть приложение, которое использует шаблоны Thymeleaf и конфигурацию Spring Boot. У меня возникла проблема с недействительным токеном CSRF при использовании некоторых конечных точек. Приложение хранит токен CSRF в файлах cookie.

На одном из шаблонов, где есть кнопка выхода, когда я не включаю никаких ссылок (таблицу стилей) и скрипты (JS) на , все работает хорошо. Но когда я включаю какие-либо заголовки или, у меня возникает проблема «Неверный токен CSRF для localhost:/logout».

Конфигурация безопасности Spring:

@Configuration
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {



    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .authenticationProvider(authenticationProvider())
                .userDetailsService(customUserDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf()
                .csrfTokenRepository(new CookieCsrfTokenRepository())
//              .disable()
                .and()
                .exceptionHandling()
                .accessDeniedPage("/dashboard")
                .and()
                    .httpBasic()
                    .disable()
                    .addFilterBefore(customFilter(), OAuth2LoginAuthenticationFilter.class)
                    .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                    .authorizeRequests()
                .antMatchers("/", "/home", "/webjars/**", "/static/**", "/css/**", "/js/**")
                .permitAll()
                    .antMatchers("/",
                        "/home",
                        "/webjars/**",
                        "/error",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js")
                    .permitAll()
                    .antMatchers("/logon","/login/**", "/oauth2_register/**","/register/**")
                    .anonymous()
                    .anyRequest()
                    .authenticated()
                .and()
                    .formLogin()
                .disable()
                    .logout()
                .deleteCookies("access_token")
                .permitAll()
                .and()
                .oauth2Login()
                    .authorizationEndpoint()
                    .authorizationRequestRepository(cookieAuthorizationRequestRepository())
                    .authorizationRequestResolver(customAuthorizationRequestResolver())
                .and()
                    .loginPage("/login")
                    .userInfoEndpoint()
                    .userService(customOAuth2UserService)
                .and()
                .successHandler(oAuth2AuthenticationSuccessHandler)
                .failureHandler(oAuth2AuthenticationFailureHandler());
    }


}


index.html, где я использую конечную точку по умолчанию «/logout», предоставленную Spring Security:

<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="'Welcome '+${user.getUsername()}+'!'"></title>

<!-- When I include the part with Bootstrap, an Invalid CSRF token error is thrown at Spring -->
    <!--Bootstrap-->
    <!--<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>-->
    <!--<link rel="stylesheet" href="/webjars/bootstrap-social/bootstrap-social.css"/>-->
    <!--<link rel="stylesheet" href="/webjars/font-awesome/css/all.css"/>-->


    <!--<script src="/webjars/jquery/jquery.min.js"></script>-->
    <!--<script src="/webjars/popper.js/popper.min.js"></script>-->
    <!--<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>-->
    <!--<script th:src="@{js/fade.js}"></script>-->

    <!--Bootstrap-->
    </head>
<body>
<div class="container">
    <div class="row justify-content-center">
        <div class="alert alert-danger" role="alert" id="backend-validation-alert" th:if="${errorMessage}">
            <span th:text="${errorMessage}"></span>
            <script>fade();</script>
        </div>
    </div>
        <h1 th:text="'Welcome '+${user.getUsername()}+'!'"></h1>

        <form role="form" th:action="@{/logout}" method="POST">
            <div><input type="submit" value="Log out"/></div>
        </form>

        <form role="form" th:action="@{/user/settings/delete}" method="POST">
            <div><input type="submit" value="Delete account"/></div>
        </form>
</div>
</body>
</html>

Когда я отлаживал код и проверял CsrfFilter, я вижу, что в шаблоне Thymeleaf для форм POST создаются другие скрытые параметры _csrf, которые не соответствуют CSRF в файле cookie, и возникает исключение. Фильтр принимает правильное значение XSRF-TOKEN в качестве токена для проверки, но токен CSRF, хранящийся в качестве параметра в запросе, неверен и отличается.

Кто-нибудь сталкивался с подобной проблемой? Когда именно должен быть сгенерирован новый токен CSRF? Потому что в моем случае, когда я проверяю информацию о сети, я вижу, что новый токен CSRF генерируется для каждого отдельного ресурса (.js, .css, .html) после входа в систему, но только токен .html CSRF сохраняется как скрытый параметр в Thymeleaf, что приводит к ошибке Invalid CSRF token.

Дополнительное примечание: я заметил, что сначала загружается исходный html, и правильные параметры формы CSRF устанавливаются как для скрытых входов HTML, так и в виде файла cookie. Но затем JS, CSS и другие файлы проходят аутентификацию CSRF, что приводит к изменению токена cookie CSRF. Я предполагаю, что решение будет включать в себя исключение этих сценариев заголовков и ссылок из аутентификации.



Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..