-
Download generated code from https://start.spring.io
-
Replace content of
DemoApplication.ktwith the following code
@SpringBootApplication
class DemoApplication
fun main(vararg args: String) {
SpringApplication.run(DemoApplication::class.java, *args)
}
@RestController
class HelloController {
@GetMapping("/public-api/hello")
fun hello(@RequestParam error: Boolean = false) =
if (error)
throw ResponseStatusException(HttpStatus.BAD_REQUEST)
else
ResponseEntity.ok().build<Unit>()
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(http: HttpSecurity) = http
.csrf().disable()
.httpBasic().disable()
.authorizeHttpRequests { requests ->
requests
.requestMatchers("/public-api/**").permitAll()
.anyRequest().authenticated()
}
.build()
}
- PROBLEM: Request
http://localhost:8080/public-api/hello?error=truereturns "403 Forbidden" - Now in
build.gradle.kts, changeid("org.springframework.boot") version "3.0.2"toid("org.springframework.boot") version "2.7.8" - In
DemoApplication.kt, changerequestMatchers("/public-api/**")toantMatchers("/public-api/**")becauserequestMatchersis not available in Spring Boot 2. - CORRECT: Request
http://localhost:8080/public-api/hello?error=truereturns "400 Bad Request" with body
{
"timestamp": "2023-01-22T13:39:18.084+00:00",
"status": 400,
"error": "Bad Request",
"path": "/public-api/hello"
}
Comment From: philwebb
By default Spring Boot 3.0 also applies security to error dispatches. In your example, the .requestMatchers("/public-api/**") filter is working but there's no equivalent rule for permitting errors.
Try adding:
requests.requestMatchers("/error").permitAll();
to your configuration.
Comment From: xuanswe
@philwebb nice. It works. Thanks!
So, in Spring 2, /error is allowed regardless of custom authorizeHttpRequests.
In Spring 3, if there's a custom authorizeHttpRequests, the default security rules are disabled. Therefore, we need to explicitly redefine them.
Comment From: mbhave
@xuan-nguyen-swe The reason why /error worked in 2.x was because we had a custom filter which checked if a user should be granted access to the error page or not. In Spring Boot 3.0, we removed the custom filter to align with Spring Security's defaults which always apply the security filter to the error dispatch.
One thing to note is that, adding permitAll to the /error page is not quite the same as the getting the behavior from Spring Boot 2.7.x back. permitAll() allows anyone to access the error page while in Spring Boot 2.7, the default was only to allow access to the error page if access to the original request was allowed. It's good to verify that public access to the error page is okay before adding permitAll. I've created an issue in Spring Security to see if this can be fixed there.
Comment From: izeye
I've created an issue in Spring Security to see if this can be fixed there.
It's pointing to a Spring Boot issue. https://github.com/spring-projects/spring-security/issues/12771 seems to be the intended one.
Comment From: mbhave
Thanks @izeye, fixed!