Springboot 3 Webflux + Spring Security CSRF отключить не работает

Сегодня я обновил демонстрационное приложение Webflux REST API с springboot 2.7.x до версии 3.0.0. При тестировании, найденном для вызовов POST с помощью SpringSecurity, я получаю 403 Forbidden с сообщением An expected CSRF token cannot be found. Я дважды проверил свою конфигурацию безопасности и не нашел никаких проблем.

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
            .csrf().disable()
            .authorizeExchange()
            .pathMatchers(HttpMethod.GET, "/actuator/**").permitAll()
            .pathMatchers(HttpMethod.POST, "/api/v1/users", "/api/v1/users/**").hasRole(ReactiveConstant.SECURITY_ROLE_ADMIN)     // Only admin can do POST
            .pathMatchers(HttpMethod.GET, "/api/v1/users", "/api/v1/users/**").hasAnyRole(ReactiveConstant.SECURITY_ROLE_USER, ReactiveConstant.SECURITY_ROLE_ADMIN)       // user can only do GET
            .anyExchange().authenticated()
            .and().formLogin()
            .and().httpBasic()
            .and().formLogin().disable()
            .build();
    }

Это работает в версии SpringBoot 2.7.5. Мой build.gradle файл,

plugins {
    id 'org.springframework.boot' version '3.0.0'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
    id 'groovy'
}

group = 'io.c12.bala'
version = '0.2.1'
sourceCompatibility = JavaVersion.VERSION_17

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-security'

    // Springboot utils
    implementation 'io.projectreactor:reactor-tools'            // For Reactor debugging in IDE
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    implementation 'org.modelmapper:modelmapper:3.1.0'
    implementation 'io.netty:netty-resolver-dns-native-macos:4.1.85.Final:osx-aarch_64'     // For macos netty DNS issue.
    implementation 'com.aventrix.jnanoid:jnanoid:2.0.0'

    // Springboot testing with Spock test framework
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'

    // Spock test framework
    testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
    testImplementation 'org.spockframework:spock-spring:2.3-groovy-4.0'

    // Reactor test framework
    testImplementation 'io.projectreactor:reactor-test'
}

test {
    useJUnitPlatform()
    maxParallelForks = Runtime.runtime.availableProcessors()
}

Я не вижу никаких изменений в CSRF в документации SpringSecurity.

Мой почтовый вызов,

curl --location --request POST 'http://localhost:8080/api/v1/users' \
--header 'Authorization: Basic am9objpIZWxsb1dvcmxkQDEyMw==' \
--header 'Content-Type: application/json' \
--data-raw '{
  "firstName": "John",
  "lastName": "Doe",
  "emailId": "[email protected]",
  "userId": "j.doe"
}'

Ответ: 403 Forbidden

An expected CSRF token cannot be found
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
0
284
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я испытал те же симптомы при переносе моего приложения webflux на Spring Boot 3.0.0 сегодня, которое отлично работало с 2.7.5. Итак, я погуглил «отключение csrf больше не работает» и нашел это и несколько (!) других сообщений …

Однако это было изменение аннотации Spring security 6, которое вызвало проблему: @EnableWebFluxSecurity содержал «@Configuration» в версии 5.x (я проверил), но, очевидно, больше не содержит и должен быть добавлен явно.

Таким образом, полный компонент SecurityWebFilterChain не был найден после миграции... Теперь рабочий код выглядит следующим образом:

@EnableWebFluxSecurity
@Configuration       // <- this annotation was missing but worked with Spring Security 5.x
public class AccountWebSecurityConfig { 

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
                                                        ReactiveAuthenticationManager authenticationManager,
                                                        ServerAccessDeniedHandler accessDeniedHandler,
                                                        ServerAuthenticationEntryPoint authenticationEntryPoint) {
    http.csrf().disable()
            .httpBasic(httpBasicSpec -> httpBasicSpec
                    .authenticationManager(authenticationManager)
                    // when moving next line to exceptionHandlingSpecs, get empty body 401 for authentication failures (e.g. Invalid Credentials)
                    .authenticationEntryPoint(authenticationEntryPoint)
            )
            .authorizeExchange()
    //...
}

Поскольку ваш фрагмент FilterChain не показывает аннотации в вашем классе, скорее всего, вы также можете пропустить @Configuration..

В моем случае теперь все работает как прежде :-)

Спасибо за Ваш ответ. Это исправило мое приложение. Мне тоже не хватало @Configuration в моем классе конфигурации безопасности.

Bala 15.12.2022 21:33

Другие вопросы по теме