【问题标题】:Springboot 3 Webflux + Spring Security CSRF disable not workingSpringboot 3 Webflux + Spring Security CSRF 禁用不起作用
【发布时间】:2022-12-15 01:47:40
【问题描述】:

今天我将我的 Webflux REST API 演示应用程序从 springboot 2.7.x 升级到版本 3.0.0。在使用 SpringSecurity 进行 POST 调用的测试中,我得到 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()
}

我在 Spring Security 文档中没有看到对 CSRF 的任何更改。

我的邮政电话,

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": "John.doe@example.com",
  "userId": "j.doe"
}'

回复:403 Forbidden

An expected CSRF token cannot be found

【问题讨论】:

    标签: spring-boot spring-security spring-webflux spring-boot-3


    【解决方案1】:

    我今天将我的 webflux 应用程序迁移到 Spring Boot 3.0.0 时遇到了相同的症状,它与 2.7.5 完美配合。所以我用谷歌搜索“csrf-disabling 不再工作”并找到了这个和一些(!)其他帖子......

    然而,在我的例子中,这是一些愚蠢的编码错误,Spring Security 版本 5(作为 Spring Boot 2.7.5 的一部分)(令人惊讶地)容忍了这个错误。

    @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 - sn-p 没有在您的课堂上显示注释,您可能还缺少 @Configuration - 因此找不到完整的 SecurityWebFilterChain bean ..

    就我而言,现在一切都像以前一样工作:-)

    【讨论】:

      猜你喜欢
      • 2018-12-12
      • 2021-05-06
      • 2020-11-21
      • 2019-11-21
      • 1970-01-01
      • 2019-09-27
      • 2020-05-09
      • 2016-06-30
      • 2011-10-05
      相关资源
      最近更新 更多