INT-4139: Add CORS Config to Graph Annotation
JIRA: https://jira.spring.io/browse/INT-4139 Doc Polishing Polishing - Fix CORS Test and Revert XML - Use standard CORS configuration with XML.
This commit is contained in:
committed by
Artem Bilan
parent
8d70463c7a
commit
3c284871c3
@@ -58,4 +58,12 @@ public @interface EnableIntegrationGraphController {
|
||||
@AliasFor("value")
|
||||
String path() default HttpContextUtils.GRAPH_CONTROLLER_DEFAULT_PATH;
|
||||
|
||||
/**
|
||||
* Specify allowed origin URLs for cross-origin request handling.
|
||||
* Only allows GET operations.
|
||||
* @return the URLs.
|
||||
* @since 4.3.5
|
||||
*/
|
||||
String[] allowedOrigins() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,14 @@ import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.http.management.IntegrationGraphController;
|
||||
import org.springframework.integration.http.support.HttpContextUtils;
|
||||
import org.springframework.integration.support.management.graph.IntegrationGraphServer;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* Registers the necessary beans for {@link EnableIntegrationGraphController}.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @since 4.3
|
||||
*/
|
||||
class IntegrationGraphControllerRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
@@ -56,6 +61,16 @@ class IntegrationGraphControllerRegistrar implements ImportBeanDefinitionRegistr
|
||||
new RootBeanDefinition(IntegrationGraphServer.class));
|
||||
}
|
||||
|
||||
String[] allowedOrigins = (String[]) annotationAttributes.get("allowedOrigins");
|
||||
if (allowedOrigins != null && allowedOrigins.length > 0) {
|
||||
AbstractBeanDefinition controllerCorsConfigurer =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(IntegrationGraphCorsConfigurer.class)
|
||||
.addConstructorArgValue(annotationAttributes.get("value"))
|
||||
.addConstructorArgValue(allowedOrigins)
|
||||
.getBeanDefinition();
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(controllerCorsConfigurer, registry);
|
||||
}
|
||||
|
||||
if (!registry.containsBeanDefinition(HttpContextUtils.GRAPH_CONTROLLER_BEAN_NAME)) {
|
||||
AbstractBeanDefinition controllerPropertiesPopulator =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GraphControllerPropertiesPopulator.class)
|
||||
@@ -98,4 +113,22 @@ class IntegrationGraphControllerRegistrar implements ImportBeanDefinitionRegistr
|
||||
|
||||
}
|
||||
|
||||
private static final class IntegrationGraphCorsConfigurer extends WebMvcConfigurerAdapter {
|
||||
|
||||
private final String path;
|
||||
|
||||
private final String[] allowedOrigins;
|
||||
|
||||
private IntegrationGraphCorsConfigurer(String path, String[] allowedOrigins) {
|
||||
this.path = path;
|
||||
this.allowedOrigins = allowedOrigins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping(this.path).allowedOrigins(this.allowedOrigins).allowedMethods("GET");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.handler;
|
||||
@@ -37,7 +38,6 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
@@ -55,15 +55,15 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @since 4.3
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -121,6 +121,11 @@ public class IntegrationGraphControllerTests {
|
||||
|
||||
Object handler = executionChain.getHandler();
|
||||
|
||||
for (HandlerInterceptor handlerInterceptor : executionChain.getInterceptors()) {
|
||||
// Assert the CORS config
|
||||
assertTrue(handlerInterceptor.preHandle(request, response, handler));
|
||||
}
|
||||
|
||||
handlerAdapter.handle(request, response, handler);
|
||||
assertEquals(HttpStatus.OK.value(), response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("\"name\":\"nullChannel\","));
|
||||
@@ -138,6 +143,11 @@ public class IntegrationGraphControllerTests {
|
||||
|
||||
handler = executionChain.getHandler();
|
||||
|
||||
for (HandlerInterceptor handlerInterceptor : executionChain.getInterceptors()) {
|
||||
// Assert the CORS config
|
||||
assertTrue(handlerInterceptor.preHandle(request, response, handler));
|
||||
}
|
||||
|
||||
handlerAdapter.handle(request, response, handler);
|
||||
assertEquals(HttpStatus.OK.value(), response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("\"name\":\"myChannel\","));
|
||||
@@ -151,16 +161,8 @@ public class IntegrationGraphControllerTests {
|
||||
@EnableIntegrationManagement(statsEnabled = "_org.springframework.integration.errorLogger.handler",
|
||||
countsEnabled = "!*",
|
||||
defaultLoggingEnabled = "false")
|
||||
@EnableIntegrationGraphController(path = "/testIntegration")
|
||||
public static class ContextConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/testIntegration/**")
|
||||
.allowedOrigins("http://foo.bar.com")
|
||||
.allowedMethods(HttpMethod.GET.name());
|
||||
|
||||
}
|
||||
@EnableIntegrationGraphController(path = "/testIntegration", allowedOrigins = "http://foo.bar.com")
|
||||
public static class ContextConfiguration {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ It is not necessary to refresh the graph for metrics, they are provided in real-
|
||||
Refresh can be called if the application context has been modified since the graph was last retrieved and the graph is completely rebuilt.
|
||||
|
||||
Any Security and Cross Origin restrictions for the `IntegrationGraphController` can be achieved with the standard configuration options and components provided by Spring Security and Spring MVC projects.
|
||||
The simple example of that may be:
|
||||
A simple example of that follows:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -236,7 +236,8 @@ The simple example of that may be:
|
||||
<int-http:graph-controller path="/myIntegration" />
|
||||
----
|
||||
|
||||
and the Java & Annotation Configuration variant is:
|
||||
The Java & Annotation Configuration variant follows; note that, for convenience, the annotation provides an `allowedOrigins` attribute; this just provides `GET` access to the `path`.
|
||||
For more sophistication, you can configure the CORS mappings using standard Spring MVC mechanisms.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -244,9 +245,8 @@ and the Java & Annotation Configuration variant is:
|
||||
@EnableWebMvc
|
||||
@EnableWebSecurity
|
||||
@EnableIntegration
|
||||
@EnableIntegrationGraphController(path = "/testIntegration")
|
||||
public class IntegrationConfiguration extends WebSecurityConfigurerAdapter
|
||||
implements WebMvcConfigurer {
|
||||
@EnableIntegrationGraphController(path = "/testIntegration", allowedOrigins="http://localhost:9090")
|
||||
public class IntegrationConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
@@ -257,13 +257,6 @@ public class IntegrationConfiguration extends WebSecurityConfigurerAdapter
|
||||
.formLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/testIntegration/**")
|
||||
.allowedOrigins("http://localhost:9090")
|
||||
.allowedMethods(HttpMethod.GET.name());
|
||||
}
|
||||
|
||||
//...
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user