Describe the bug When I upgraded my Spring Boot project from 2.7.7 to 3.0.1, the H2 console browser access is denied (403).
To Reproduce Here is the code snippet for Spring Boot 2.7.7 security configuration.
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.antMatchers("/h2-console/**").permitAll()
)
.headers(headers -> headers.frameOptions().disable())
.csrf(csrf -> csrf
.ignoringAntMatchers("/h2-console/**"));
return http.build();
}
}
Here is the code snippet for Spring Boot 3.0.1 security configuration.
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/h2-console/**").permitAll()
)
.headers(headers -> headers.frameOptions().disable())
.csrf(csrf -> csrf
.ignoringRequestMatchers("/h2-console/**"));
return http.build();
}
}
I have included a link to a simple Spring Boot project that uses H2 database for reproduction. https://github.com/Washingtonwei/spring-security-6-h2-console-problem - The first commit to the main branch is Spring Boot 2.7.7. The H2 console works as expected. - The second commit to the main branch is Spring Boot 3.0.1. The H2 console access is denied.
Expected behavior
When we enter "localhost:8080/h2-console" in a browser address bar, the H2 console page is supposed to appear.
However, in Spring Security 6, 403 is returned.
Sample A link to a GitHub repository with a minimal, reproducible sample: https://github.com/Washingtonwei/spring-security-6-h2-console-problem
- The first commit to the main branch is Spring Boot 2.7.7. The H2 console works as expected.
- The second commit to the main branch is Spring Boot 3.0.1. The H2 console access is denied.
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: jfbourner
I had the same issue last night. I Found this and it worked for me. https://stackoverflow.com/questions/74680244/h2-database-console-not-opening-with-spring-security
.authorizeHttpRequests(auth -> auth
.requestMatchers(toH2Console()).permitAll()
.csrf(csrf -> csrf
.ignoringRequestMatchers(toH2Console())
Comment From: Washingtonwei
I had the same issue last night. I Found this and it worked for me. https://stackoverflow.com/questions/74680244/h2-database-console-not-opening-with-spring-security
.authorizeHttpRequests(auth -> auth .requestMatchers(toH2Console()).permitAll().csrf(csrf -> csrf .ignoringRequestMatchers(toH2Console())
Thanks for the solution. If Spring MVC is used, then by default auth.requestMatchers() will use the MvcRequestMatcher. Since H2 console is not controlled by Spring MVC, we must use AntPathRequestMatcher.
PathRequest.toH2Console() works in terms of opening the H2 console page, but it makes my integration tests fail:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.autoconfigure.h2.H2ConsoleProperties' available
After reading the post provided by you, I prefer to use auth.requestMatchers(AntPathRequestMatcher.antMatcher("/h2-console/**")).permitAll() It clearly shows which matcher I am using.
The below code works well:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers(AntPathRequestMatcher.antMatcher("/h2-console/**")).permitAll()
)
.headers(headers -> headers.frameOptions().disable())
.csrf(csrf -> csrf
.ignoringRequestMatchers(AntPathRequestMatcher.antMatcher("/h2-console/**")));
return http.build();
}
}
Comment From: marcusdacoregio
Hello everyone, thanks for the report.
This is a duplicate of https://github.com/spring-projects/spring-security/issues/12310#issuecomment-1328990026
Comment From: RufusWein
Comment From: Temzu
Spring boot 3 H2 config:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf
.ignoringRequestMatchers(toH2Console())
.disable()
)
.authorizeHttpRequests(auth -> auth
.requestMatchers(toH2Console()).permitAll()
)
.headers(headers -> headers.frameOptions(FrameOptionsConfig::disable));
return http.build();
}