@Test // SPR-15772 public void changePermitDefaultValues() { CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues(); config.addAllowedOrigin("http://domain.com"); config.addAllowedHeader("header1"); config.addAllowedMethod("PATCH"); assertEquals(Arrays.asList("*", "http://domain.com"), config.getAllowedOrigins()); assertEquals(Arrays.asList("*", "header1"), config.getAllowedHeaders()); assertEquals(Arrays.asList("GET", "HEAD", "POST", "PATCH"), config.getAllowedMethods()); }
@Override protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) { HandlerMethod handlerMethod = createHandlerMethod(handler, method); Class<?> beanType = handlerMethod.getBeanType(); CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class); CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class); if (typeAnnotation == null && methodAnnotation == null) { return null; } CorsConfiguration config = new CorsConfiguration(); updateCorsConfig(config, typeAnnotation); updateCorsConfig(config, methodAnnotation); if (CollectionUtils.isEmpty(config.getAllowedMethods())) { for (RequestMethod allowedMethod : mappingInfo.getMethodsCondition().getMethods()) { config.addAllowedMethod(allowedMethod.name()); } } return config.applyPermitDefaultValues(); }
@Override protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) { HandlerMethod handlerMethod = createHandlerMethod(handler, method); Class<?> beanType = handlerMethod.getBeanType(); CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class); CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class); if (typeAnnotation == null && methodAnnotation == null) { return null; } CorsConfiguration config = new CorsConfiguration(); updateCorsConfig(config, typeAnnotation); updateCorsConfig(config, methodAnnotation); if (CollectionUtils.isEmpty(config.getAllowedMethods())) { for (RequestMethod allowedMethod : mappingInfo.getMethodsCondition().getMethods()) { config.addAllowedMethod(allowedMethod.name()); } } return config.applyPermitDefaultValues(); }
@Test public void customizedMapping() { this.registry.addMapping("/foo").allowedOrigins("http://domain2.com", "http://domain2.com") .allowedMethods("DELETE").allowCredentials(false).allowedHeaders("header1", "header2") .exposedHeaders("header3", "header4").maxAge(3600); Map<String, CorsConfiguration> configs = this.registry.getCorsConfigurations(); assertEquals(1, configs.size()); CorsConfiguration config = configs.get("/foo"); assertEquals(Arrays.asList("http://domain2.com", "http://domain2.com"), config.getAllowedOrigins()); assertEquals(Arrays.asList("DELETE"), config.getAllowedMethods()); assertEquals(Arrays.asList("header1", "header2"), config.getAllowedHeaders()); assertEquals(Arrays.asList("header3", "header4"), config.getExposedHeaders()); assertEquals(false, config.getAllowCredentials()); assertEquals(Long.valueOf(3600), config.getMaxAge()); }
@Test // SPR-13468 public void classLevelComposedAnnotation() throws Exception { this.handlerMapping.registerHandler(new ClassLevelMappingWithComposedAnnotation()); this.request.setRequestURI("/foo"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, false); assertNotNull(config); assertArrayEquals(new String[] {"GET"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"http://foo.com"}, config.getAllowedOrigins().toArray()); assertTrue(config.getAllowCredentials()); }
@Test public void getCorsConfigurationActual() throws Exception { AnnotationConfigWebApplicationContext cxt = new AnnotationConfigWebApplicationContext(); cxt.register(TestConfig.class); cxt.refresh(); MockHttpServletRequest request = new MockHttpServletRequest("POST", "/path"); request.addHeader("Origin", "http://localhost:9000"); CorsConfiguration corsConfig = getIntrospector(cxt).getCorsConfiguration(request); assertNotNull(corsConfig); assertEquals(Collections.singletonList("http://localhost:9000"), corsConfig.getAllowedOrigins()); assertEquals(Collections.singletonList("POST"), corsConfig.getAllowedMethods()); }
@Test public void customizedMapping() { this.registry.addMapping("/foo").allowedOrigins("http://domain2.com", "http://domain2.com") .allowedMethods("DELETE").allowCredentials(false).allowedHeaders("header1", "header2") .exposedHeaders("header3", "header4").maxAge(3600); Map<String, CorsConfiguration> configs = this.registry.getCorsConfigurations(); assertEquals(1, configs.size()); CorsConfiguration config = configs.get("/foo"); assertEquals(Arrays.asList("http://domain2.com", "http://domain2.com"), config.getAllowedOrigins()); assertEquals(Arrays.asList("DELETE"), config.getAllowedMethods()); assertEquals(Arrays.asList("header1", "header2"), config.getAllowedHeaders()); assertEquals(Arrays.asList("header3", "header4"), config.getExposedHeaders()); assertEquals(false, config.getAllowCredentials()); assertEquals(Long.valueOf(3600), config.getMaxAge()); }
@Test public void defaultAnnotation() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); this.request.setRequestURI("/default"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, false); assertNotNull(config); assertArrayEquals(new String[] {"GET"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedOrigins().toArray()); assertNull(config.getAllowCredentials()); assertArrayEquals(new String[] {"*"}, config.getAllowedHeaders().toArray()); assertTrue(CollectionUtils.isEmpty(config.getExposedHeaders())); assertEquals(new Long(1800), config.getMaxAge()); }
@Test public void customized() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); this.request.setRequestURI("/customized"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, false); assertNotNull(config); assertArrayEquals(new String[] {"DELETE"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"http://site1.com", "http://site2.com"}, config.getAllowedOrigins().toArray()); assertArrayEquals(new String[] {"header1", "header2"}, config.getAllowedHeaders().toArray()); assertArrayEquals(new String[] {"header3", "header4"}, config.getExposedHeaders().toArray()); assertEquals(new Long(123), config.getMaxAge()); assertFalse(config.getAllowCredentials()); }
@Test // SPR-13468 public void methodLevelComposedAnnotation() throws Exception { this.handlerMapping.registerHandler(new MethodLevelMappingWithComposedAnnotation()); this.request.setRequestURI("/foo"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, false); assertNotNull(config); assertArrayEquals(new String[] {"GET"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"http://foo.com"}, config.getAllowedOrigins().toArray()); assertTrue(config.getAllowCredentials()); }
@Test public void combineWithAsteriskWildCard() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); CorsConfiguration other = new CorsConfiguration(); other.addAllowedOrigin("http://domain.com"); other.addAllowedHeader("header1"); other.addExposedHeader("header2"); other.addAllowedMethod(HttpMethod.PUT.name()); CorsConfiguration combinedConfig = config.combine(other); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedOrigins()); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedHeaders()); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedMethods()); combinedConfig = other.combine(config); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedOrigins()); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedHeaders()); assertEquals(Arrays.asList("*"), combinedConfig.getAllowedMethods()); }
@Test public void getCorsConfigurationPreFlight() throws Exception { AnnotationConfigWebApplicationContext cxt = new AnnotationConfigWebApplicationContext(); cxt.register(TestConfig.class); cxt.refresh(); // PRE-FLIGHT MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/path"); request.addHeader("Origin", "http://localhost:9000"); request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"); CorsConfiguration corsConfig = getIntrospector(cxt).getCorsConfiguration(request); assertNotNull(corsConfig); assertEquals(Collections.singletonList("http://localhost:9000"), corsConfig.getAllowedOrigins()); assertEquals(Collections.singletonList("POST"), corsConfig.getAllowedMethods()); }
@Test public void setValues() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); assertEquals(Arrays.asList("*"), config.getAllowedOrigins()); config.addAllowedHeader("*"); assertEquals(Arrays.asList("*"), config.getAllowedHeaders()); config.addAllowedMethod("*"); assertEquals(Arrays.asList("*"), config.getAllowedMethods()); config.addExposedHeader("header1"); config.addExposedHeader("header2"); assertEquals(Arrays.asList("header1", "header2"), config.getExposedHeaders()); config.setAllowCredentials(true); assertTrue(config.getAllowCredentials()); config.setMaxAge(123L); assertEquals(new Long(123), config.getMaxAge()); }
@Test public void preFlightRequest() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); this.request.setMethod("OPTIONS"); this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); this.request.setRequestURI("/default"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, true); assertNotNull(config); assertArrayEquals(new String[] {"GET"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedOrigins().toArray()); assertNull(config.getAllowCredentials()); assertArrayEquals(new String[] {"*"}, config.getAllowedHeaders().toArray()); assertTrue(CollectionUtils.isEmpty(config.getExposedHeaders())); assertEquals(new Long(1800), config.getMaxAge()); }
@Test public void testCorsMinimal() throws Exception { loadBeanDefinitions("mvc-config-cors-minimal.xml"); String[] beanNames = appContext.getBeanNamesForType(AbstractHandlerMapping.class); assertEquals(2, beanNames.length); for (String beanName : beanNames) { AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping)appContext.getBean(beanName); assertNotNull(handlerMapping); DirectFieldAccessor accessor = new DirectFieldAccessor(handlerMapping); Map<String, CorsConfiguration> configs = ((UrlBasedCorsConfigurationSource)accessor .getPropertyValue("corsConfigurationSource")).getCorsConfigurations(); assertNotNull(configs); assertEquals(1, configs.size()); CorsConfiguration config = configs.get("/**"); assertNotNull(config); assertArrayEquals(new String[]{"*"}, config.getAllowedOrigins().toArray()); assertArrayEquals(new String[]{"GET", "HEAD", "POST"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[]{"*"}, config.getAllowedHeaders().toArray()); assertNull(config.getExposedHeaders()); assertNull(config.getAllowCredentials()); assertEquals(Long.valueOf(1800), config.getMaxAge()); } }
@Test public void ambiguousProducesPreFlightRequest() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); this.request.setMethod("OPTIONS"); this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); this.request.setRequestURI("/ambiguous-produces"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, true); assertNotNull(config); assertArrayEquals(new String[] {"*"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedOrigins().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedHeaders().toArray()); assertTrue(config.getAllowCredentials()); assertTrue(CollectionUtils.isEmpty(config.getExposedHeaders())); assertNull(config.getMaxAge()); }
@Test public void combineWithNullProperties() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.addAllowedHeader("header1"); config.addExposedHeader("header3"); config.addAllowedMethod(HttpMethod.GET.name()); config.setMaxAge(123L); config.setAllowCredentials(true); CorsConfiguration other = new CorsConfiguration(); config = config.combine(other); assertEquals(Arrays.asList("*"), config.getAllowedOrigins()); assertEquals(Arrays.asList("header1"), config.getAllowedHeaders()); assertEquals(Arrays.asList("header3"), config.getExposedHeaders()); assertEquals(Arrays.asList(HttpMethod.GET.name()), config.getAllowedMethods()); assertEquals(new Long(123), config.getMaxAge()); assertTrue(config.getAllowCredentials()); }
@Test public void ambiguousHeaderPreFlightRequest() throws Exception { this.handlerMapping.registerHandler(new MethodLevelController()); this.request.setMethod("OPTIONS"); this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "header1"); this.request.setRequestURI("/ambiguous-header"); HandlerExecutionChain chain = this.handlerMapping.getHandler(request); CorsConfiguration config = getCorsConfiguration(chain, true); assertNotNull(config); assertArrayEquals(new String[] {"*"}, config.getAllowedMethods().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedOrigins().toArray()); assertArrayEquals(new String[] {"*"}, config.getAllowedHeaders().toArray()); assertTrue(config.getAllowCredentials()); assertTrue(CollectionUtils.isEmpty(config.getExposedHeaders())); assertNull(config.getMaxAge()); }
@Test public void combine() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("http://domain1.com"); config.addAllowedHeader("header1"); config.addExposedHeader("header3"); config.addAllowedMethod(HttpMethod.GET.name()); config.setMaxAge(123L); config.setAllowCredentials(true); CorsConfiguration other = new CorsConfiguration(); other.addAllowedOrigin("http://domain2.com"); other.addAllowedHeader("header2"); other.addExposedHeader("header4"); other.addAllowedMethod(HttpMethod.PUT.name()); other.setMaxAge(456L); other.setAllowCredentials(false); config = config.combine(other); assertEquals(Arrays.asList("http://domain1.com", "http://domain2.com"), config.getAllowedOrigins()); assertEquals(Arrays.asList("header1", "header2"), config.getAllowedHeaders()); assertEquals(Arrays.asList("header3", "header4"), config.getExposedHeaders()); assertEquals(Arrays.asList(HttpMethod.GET.name(), HttpMethod.PUT.name()), config.getAllowedMethods()); assertEquals(new Long(456), config.getMaxAge()); assertFalse(config.getAllowCredentials()); }
@Test public void setNullValues() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(null); assertNull(config.getAllowedOrigins()); config.setAllowedHeaders(null); assertNull(config.getAllowedHeaders()); config.setAllowedMethods(null); assertNull(config.getAllowedMethods()); config.setExposedHeaders(null); assertNull(config.getExposedHeaders()); config.setAllowCredentials(null); assertNull(config.getAllowCredentials()); config.setMaxAge(null); assertNull(config.getMaxAge()); }