#spring #spring-mvc #spring-boot #cors #cross-domain
#spring #spring-mvc #spring-boot #cors #междоменный
Вопрос:
Я бы хотел запретить моему REST API совместное использование ресурсов из разных источников. К сожалению, я застрял в каком-то странном случае, связанном с Spring MVC или Spring Boot.
Чтобы не обвинять другие библиотеки, я взял clean Spring Boot 1.4 и воссоздал проблему.
1. Только одна конечная точка / тест
@RestController
@RequestMapping(value = "/test", produces = "application/v1")
public class Endpoint1 {
@RequestMapping(method = RequestMethod.PUT)
public void put() {
}
}
Запрос cors для проверки перед выполнением:
# Request
curl -I -X OPTIONS -H "Access-Control-Request-Method:PUT" -H "Origin:http://evilpage.com" -H "Accept: application/v2" localhost:8080/test
# Response
HTTP/1.1 403
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 20
Date: Thu, 06 Oct 2016 18:38:36 GMT
Все в порядке — запрос CORS невозможен. Заголовок: Access-Control-Allow-Origin не представлен.
2. Две конечные точки / тест, версия которых определяется заголовком Accept
Я только что добавил вторую конечную точку с помощью path / test.
@RestController
@RequestMapping(value = "/test", produces = "application/test2")
public class Endpoint2 {
@RequestMapping(method = RequestMethod.PUT)
public void put() {
}
}
Еще раз проверьте, какие параметры вернет запрос:
# Request
curl -I -X OPTIONS -H "Access-Control-Request-Method:PUT" -H "Origin:http://evilpage.com" -H "Accept: application/test2" localhost:8080/test
# Response
HTTP/1.1 200
Access-Control-Allow-Origin: http://evilpage.com
Vary: Origin
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Credentials: true
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Thu, 06 Oct 2016 18:40:41 GMT
… и что-то (Spring boot или mvc) устанавливает Access-Control-Allow-Origin в ответ! Почему?
Результат: браузер запрашивает мою службу (используя предполетный запрос параметров cors), может ли он отправить запрос PUT по источникам. Мой сервис воспроизводит «нет проблем». Запрос PUT из источника различий обрабатывается моей службой.
Что я хотел бы знать:
- Как это возможно? Как работает этот механизм?
- Как предотвратить такое поведение моего API?
Заранее благодарим вас за помощь!
Код: https://github.com/wareq/sof-39903769/tree/master/src/main/java/com/warek — Я добавил только два класса с определениями конечных точек
Ответ №1:
Я нашел решение — регистрация фильтра непосредственно в сервлет. Хм .. может быть, есть лучшее решение?
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin(null);
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}