forked from spring-projects/spring-boot
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add auto-configuration for H2’s web console
Three conditions must be met for the console to be enabled: - H2 is on the classpath - The application is a web application - spring.h2.console.enabled is set to true If spring-boot-devtools is on the classpath, spring.h2.console.enabled will be set to true automatically. Without the dev tools, the enabled property will have to be set to true in application.properties. By default, the console is available at /h2-console. This can be configured via the spring.h2.console.path property. The value of this property must begin with a '/'. When Spring Security is on the classpath the console will be secured based on the user's security.* configuration. When the console is secured, CSRF protection is disabled and frame options is set to SAMEORIGIN for its path. Both settings are required in order for the console to function. Closes spring-projectsgh-766
- Loading branch information
1 parent
f95c95a
commit 2a5a32b
Showing
9 changed files
with
431 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
...e/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* Copyright 2012-2015 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 | ||
* | ||
* http://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.autoconfigure.h2; | ||
|
||
import org.h2.server.web.WebServlet; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.autoconfigure.AutoConfigureAfter; | ||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | ||
import org.springframework.boot.autoconfigure.security.SecurityAuthorizeMode; | ||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.security.SecurityProperties; | ||
import org.springframework.boot.context.embedded.ServletRegistrationBean; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.annotation.Order; | ||
import org.springframework.security.config.annotation.ObjectPostProcessor; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||
|
||
/** | ||
* {@link EnableAutoConfiguration Auto-configuration} for H2's web console | ||
* | ||
* @author Andy Wilkinson | ||
* @since 1.3.0 | ||
*/ | ||
@Configuration | ||
@ConditionalOnWebApplication | ||
@ConditionalOnClass(WebServlet.class) | ||
@ConditionalOnProperty(prefix = "spring.h2.console", name = "enabled", havingValue = "true", matchIfMissing = false) | ||
@EnableConfigurationProperties(H2ConsoleProperties.class) | ||
@AutoConfigureAfter(SecurityAutoConfiguration.class) | ||
public class H2ConsoleAutoConfiguration { | ||
|
||
@Autowired | ||
private H2ConsoleProperties properties; | ||
|
||
@Bean | ||
public ServletRegistrationBean h2Console() { | ||
return new ServletRegistrationBean(new WebServlet(), this.properties.getPath() | ||
.endsWith("/") ? this.properties.getPath() + "*" | ||
: this.properties.getPath() + "/*"); | ||
} | ||
|
||
@Configuration | ||
@ConditionalOnClass(WebSecurityConfigurerAdapter.class) | ||
@ConditionalOnBean(ObjectPostProcessor.class) | ||
@ConditionalOnProperty(prefix = "security.basic", name = "enabled", matchIfMissing = true) | ||
static class H2ConsoleSecurityConfiguration { | ||
|
||
@Bean | ||
public WebSecurityConfigurerAdapter h2ConsoleSecurityConfigurer() { | ||
return new H2ConsoleSecurityConfigurer(); | ||
} | ||
|
||
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10) | ||
private static class H2ConsoleSecurityConfigurer extends | ||
WebSecurityConfigurerAdapter { | ||
|
||
@Autowired | ||
private H2ConsoleProperties console; | ||
|
||
@Autowired | ||
private SecurityProperties security; | ||
|
||
@Override | ||
public void configure(HttpSecurity http) throws Exception { | ||
HttpSecurity h2Console = http.antMatcher(this.console.getPath().endsWith( | ||
"/") ? this.console.getPath() + "**" : this.console.getPath() | ||
+ "/**"); | ||
h2Console.csrf().disable(); | ||
h2Console.httpBasic(); | ||
h2Console.headers().frameOptions().sameOrigin(); | ||
String[] roles = this.security.getUser().getRole().toArray(new String[0]); | ||
SecurityAuthorizeMode mode = this.security.getBasic().getAuthorizeMode(); | ||
if (mode == null || mode == SecurityAuthorizeMode.ROLE) { | ||
http.authorizeRequests().anyRequest().hasAnyRole(roles); | ||
} | ||
else if (mode == SecurityAuthorizeMode.AUTHENTICATED) { | ||
http.authorizeRequests().anyRequest().authenticated(); | ||
} | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
...onfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright 2012-2015 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 | ||
* | ||
* http://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.autoconfigure.h2; | ||
|
||
import javax.validation.constraints.NotNull; | ||
import javax.validation.constraints.Pattern; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
/** | ||
* Configuration properties for H2's console | ||
* | ||
* @author Andy Wilkinson | ||
* @since 1.3.0 | ||
*/ | ||
@ConfigurationProperties(prefix = "spring.h2.console") | ||
public class H2ConsoleProperties { | ||
|
||
/** | ||
* Path at which the console will be available. | ||
*/ | ||
@NotNull | ||
@Pattern(regexp = "/[^?#]*", message = "Path must start with /") | ||
private String path = "/h2-console"; | ||
|
||
/** | ||
* Enable the console. | ||
*/ | ||
private boolean enabled = false; | ||
|
||
public String getPath() { | ||
return this.path; | ||
} | ||
|
||
public void setPath(String path) { | ||
this.path = path; | ||
} | ||
|
||
public boolean getEnabled() { | ||
return this.enabled; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
...org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationIntegrationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright 2012-2015 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 | ||
* | ||
* http://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.autoconfigure.h2; | ||
|
||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfigurationIntegrationTests.TestConfiguration; | ||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.Import; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.test.context.ContextConfiguration; | ||
import org.springframework.test.context.TestPropertySource; | ||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||
import org.springframework.test.context.web.WebAppConfiguration; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.context.WebApplicationContext; | ||
|
||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; | ||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; | ||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
/** | ||
* Integration tests for {@link H2ConsoleAutoConfiguration} | ||
* | ||
* @author Andy Wilkinson | ||
*/ | ||
@RunWith(SpringJUnit4ClassRunner.class) | ||
@WebAppConfiguration | ||
@ContextConfiguration(classes = TestConfiguration.class) | ||
@TestPropertySource(properties = "spring.h2.console.enabled:true") | ||
public class H2ConsoleAutoConfigurationIntegrationTests { | ||
|
||
@Autowired | ||
private WebApplicationContext context; | ||
|
||
@Test | ||
public void noPrincipal() throws Exception { | ||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) | ||
.apply(springSecurity()).build(); | ||
mockMvc.perform(get("/h2-console/")).andExpect(status().isUnauthorized()); | ||
} | ||
|
||
@Test | ||
public void userPrincipal() throws Exception { | ||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) | ||
.apply(springSecurity()).build(); | ||
mockMvc.perform(get("/h2-console/").with(user("test").roles("USER"))) | ||
.andExpect(status().isOk()) | ||
.andExpect(header().string("X-Frame-Options", "SAMEORIGIN")); | ||
} | ||
|
||
@Test | ||
public void someOtherPrincipal() throws Exception { | ||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) | ||
.apply(springSecurity()).build(); | ||
mockMvc.perform(get("/h2-console/").with(user("test").roles("FOO"))).andExpect( | ||
status().isForbidden()); | ||
} | ||
|
||
@Configuration | ||
@Import({ SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, | ||
H2ConsoleAutoConfiguration.class }) | ||
@Controller | ||
static class TestConfiguration { | ||
|
||
@RequestMapping("/h2-console/**") | ||
public void mockConsole() { | ||
|
||
} | ||
} | ||
|
||
} |
Oops, something went wrong.