Bal*_*ala 1 spring-security spring-boot spring-webflux
今天我将我的 Webflux REST API 演示应用程序从 springboot 升级2.7.x到了 version 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();
}
Run Code Online (Sandbox Code Playgroud)
这适用于 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()
}
Run Code Online (Sandbox Code Playgroud)
我在 SpringSecurity 文档中没有看到 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"
}'
Run Code Online (Sandbox Code Playgroud)
回复:403 Forbidden
An expected CSRF token cannot be found
Run Code Online (Sandbox Code Playgroud)
我今天将 webflux 应用程序迁移到 Spring Boot 3.0.0 时遇到了同样的症状,它与 2.7.5 完美配合。所以我在谷歌上搜索“csrf-disabling不再起作用”并发现了这个和一些(!)其他帖子......
然而,这是 Spring security 6 的注释更改导致了问题:@EnableWebFluxSecurity 在 5.x 版本中包含“@Configuration”(我检查过) - 但显然不再包含,必须显式添加。
因此,迁移后找不到完整的 SecurityWebFilterChain bean...现在工作代码如下所示:
@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()
//...
}
Run Code Online (Sandbox Code Playgroud)
由于您的 FilterChain - 代码片段没有在您的类中显示注释,因此您可能还缺少 @Configuration ..
就我而言,现在一切都像以前一样工作:-)
| 归档时间: |
|
| 查看次数: |
2203 次 |
| 最近记录: |