My ultimate goal is the use the h2db-web-console in my application, as part of my local dev environment.
I'm getting the error:
Caused by: java.lang.IllegalArgumentException: This method cannot decide whether these patterns are Spring MVC patterns or not. If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher).
This is because there is more than one mappable servlet in your servlet context: {org.h2.server.web.JakartaWebServlet=[/my-h2-console/*], org.springframework.web.servlet.DispatcherServlet=[/]}.
For each MvcRequestMatcher, call MvcRequestMatcher#setServletPath to indicate the servlet path.
While this sounds pretty descriptive it drives me crazy, since it appears it doesn't matter which path I use for JakartaWebServlet=[/my-h2-console/*], since DispatcherServlet=[/] simply matches everything. that starts with "/"...which is everything.
...please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher)...
Well, those are deprecated with Spring 3.x.x patchnotes so I've tried using the RequestMatcher(this should be automatically be used with 'authorize') instead.
Security-Config
@Bean
@Order(GENERAL_SECURITY_CONFIGURATION_ORDER)
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
...
}
securityMatcher("/**")
headers { frameOptions { disable() } }
csrf { ignoringRequestMatchers("/my-h2-console/**") }
authorizeRequests {
authorize("/my-h2-console/**", permitAll)
authorize("/ping", permitAll)
authorize("/**", denyAll)
}
}
return http.build()
}
pom.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope> <!-- Should be "test", revert later -->
</dependency>
application.yml
spring:
h2:
console:
enabled: true
path: /my-h2-console
settings:
trace: false
web-allow-others: false
datasource:
url: jdbc:h2:mem:testdb
driverClassName: org.h2.Driver
username: sa
password:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
sql:
init:
mode: embedded
schema-locations: classpath:sql/schema.testdb.local.sql
Please keep in mind, I'm new to spring-boot in general, so please be gentle. Any kind of information regarding this topic is kindly appreciated. :)
I tried:
=> Only turning off/on
spring:
h2:
console:
enabled: true
seems to bring any change.
This configuration helped me to resolve H2 issue:
@Configuration
public class SecurityConfig {
// My enpdoints start from /v1 so this pattern is ok for me
private static final String API_URL_PATTERN = "/v1/**";
@Bean
public SecurityFilterChain getSecurityFilterChain(HttpSecurity http,
HandlerMappingIntrospector introspector) throws Exception {
MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
http.csrf(csrfConfigurer ->
csrfConfigurer.ignoringRequestMatchers(mvcMatcherBuilder.pattern(API_URL_PATTERN),
PathRequest.toH2Console()));
http.headers(headersConfigurer ->
headersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));
http.authorizeHttpRequests(auth ->
auth
.requestMatchers(mvcMatcherBuilder.pattern(API_URL_PATTERN)).permitAll()
//This line is optional in .authenticated() case as .anyRequest().authenticated()
//would be applied for H2 path anyway
.requestMatchers(PathRequest.toH2Console()).authenticated()
.anyRequest().authenticated()
);
http.formLogin(Customizer.withDefaults());
http.httpBasic(Customizer.withDefaults());
return http.build();
}
}
More info.
Updated code for H2 console to work properly in browser.
Also PathRequest.toH2Console()
could be used instead of AntPathRequestMatcher.antMatcher("/h2-console/**")