diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/sql.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/sql.adoc index 301a07dd65..3db0cecfc6 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/sql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/sql.adoc @@ -322,6 +322,28 @@ You can customize the console's path by using the configprop:spring.h2.console.p +[[features.sql.h2-web-console.spring-security]] +==== Configuring Spring Security for H2 Console +H2 Console uses frames and, as it's intended for development only, does not implement CSRF protection measures. If your application uses Spring Security, you need to configure it to + +* disable CSRF protection for requests against the console, +* set the header `X-Frame-Options` to `SAMEORIGIN` on responses from the console. + +More information on {spring-security-docs}#csrf[CSRF] and the header {spring-security-docs}#headers-frame-options[X-Frame-Options] can be found in the Spring Security Reference Guide. + +In simple setups, a `SecurityFilterChain` like the following can be used: + +[source,java,indent=0,subs="verbatim"] +---- +include::{docs-java}/features/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java[] +---- + +WARNING: The H2 console is only intended for use during development. In production, disabling CSRF protection or allowing frames for a website may create severe security risks. + +TIP: `PathRequest.toH2Console()` returns the correct request matcher also when the console's path has been customized. + + + [[features.sql.jooq]] === Using jOOQ jOOQ Object Oriented Querying (https://www.jooq.org/[jOOQ]) is a popular product from https://www.datageekery.com/[Data Geekery] which generates Java code from your database and lets you build type-safe SQL queries through its fluent API. diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java new file mode 100644 index 0000000000..88eb90d875 --- /dev/null +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.docs.features.sql.h2webconsole.springsecurity; + +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +@Profile("dev") +@Configuration(proxyBeanMethods = false) +public class DevProfileSecurityConfiguration { + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception { + // @formatter:off + return http.requestMatcher(PathRequest.toH2Console()) + // ... configuration for authorization + .csrf().disable() + .headers().frameOptions().sameOrigin().and() + .build(); + // @formatter:on + } + +}