From 57a51ed2890bfead85d82a9816623a9d58769b95 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 11 May 2015 10:34:39 +0100 Subject: [PATCH] =?UTF-8?q?Update=20configuration=20of=20Jolokia=E2=80=99s?= =?UTF-8?q?=20AgentServlet=20to=20support=20CORS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spring Framework 4.2 introduces improved support for CORS. Notably this means that a DispatcherServlet will now process an OPTIONS request if it contains an Origin header, without having to enable OPTIONS request dispatching for every endpoint. This commit takes advantage of these changes in Spring Framework 4.2 by configuring the controller that wraps Jolokia’s AgentServlet to handle OPTIONS requests. This allows Jolokia’s CORS support to be configured using Jolokia’s standard configuration, as described in section 4.1.5 of the Jolokia documentation [1]. Closes gh-1987 [1] https://jolokia.org/reference/html/security.html --- .../endpoint/mvc/EndpointHandlerMapping.java | 3 ++- .../actuate/endpoint/mvc/JolokiaMvcEndpoint.java | 1 + .../endpoint/mvc/JolokiaMvcEndpointTests.java | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java index 74cb67ed96f..382daf7a9af 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java @@ -47,6 +47,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl * @author Phillip Webb * @author Christian Dupuis * @author Dave Syer + * @author Andy Wilkinson */ public class EndpointHandlerMapping extends RequestMappingHandlerMapping implements ApplicationContextAware { @@ -95,7 +96,7 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping impleme return; } String[] patterns = getPatterns(handler, mapping); - super.registerHandlerMethod(handler, method, withNewPatterns(mapping, patterns)); + super.registerMapping(withNewPatterns(mapping, patterns), handler, method); } private String[] getPatterns(Object handler, RequestMappingInfo mapping) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java index 71152270bfc..d95b3a4371c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpoint.java @@ -71,6 +71,7 @@ public class JolokiaMvcEndpoint implements MvcEndpoint, InitializingBean, this.path = "/jolokia"; this.controller.setServletClass(AgentServlet.class); this.controller.setServletName("jolokia"); + this.controller.setSupportedMethods("GET", "POST", "HEAD", "OPTIONS"); } @Override diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java index 9b02bb663c1..d805f4d52c9 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java @@ -32,6 +32,7 @@ import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.http.HttpHeaders; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; @@ -43,7 +44,9 @@ import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -51,6 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * * @author Christian Dupuis * @author Dave Syer + * @author Andy Wilkinson */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { Config.class }) @@ -99,6 +103,15 @@ public class JolokiaMvcEndpointTests { .andExpect(content().string(containsString("NonHeapMemoryUsage"))); } + @Test + public void corsOptionsRequest() throws Exception { + this.mvc.perform( + options("/jolokia/read/java.lang:type=Memory").header(HttpHeaders.ORIGIN, + "example.com").header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, + "GET")).andExpect( + header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "example.com")); + } + @Configuration @EnableConfigurationProperties @EnableWebMvc