Spring Фильтр загрузки CORS - канал предпросмотра CORS не удался
Мне нужно добавить фильтр CORS в мое веб-приложение загрузки Spring.
Я добавил сопоставления CORS, как описано в следующей документации http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
Это моя конфигурация:
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
// @formatter:off
registry
.addMapping("/**")
.allowedOrigins(CrossOrigin.DEFAULT_ORIGINS)
.allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600L);
// @formatter:on
}
...
}
Сейчас, когда я пытаюсь получить доступ к моему API, я получаю следующую ошибку:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com/api/v1.0/user. (Reason: CORS preflight channel did not succeed).
Это скриншот из консоли FF:
![введите описание изображения здесь]()
Что я делаю неправильно и как правильно настроить заголовки CORS, чтобы избежать этой проблемы?
Ответы
Ответ 1
Я исправил эту проблему, создав новый фильтр CORS:
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
и добавил его в конфигурацию securty:
.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class)
ОБНОВЛЕНО - более современный способ, с которого я переключился:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
...
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Ответ 2
Если бы одна и та же проблема позволяла CORS работать с остатком данных spring, это был код фильтра, который я использовал.
/**
* Until url{https://jira.spring.io/browse/DATAREST-573} is fixed
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Ответ 3
Для чего это стоило, для меня работало следующее комбинированное решение:
1.
@Configuration
public class CorsConfiguration {
//This can be used in combination with @CrossOrigin on the controller & method.
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD","OPTIONS")
.allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept");
}
};
}
}
2. @CrossOrigin
в классе RestController. Имея @CrossOrigin
, читаем аннотации @RequestMapping
и методы HTTP в нем. Остальные запросы отклоняются с ошибкой CORS.
Но вам будет не повезло с вышеупомянутым решением, если вы хотите использовать spring безопасность в своем проекте.
Я использую spring версию для загрузки 1.5.4.RELEASE.
Ответ 4
Это очень просто и работает хорошо. В классе, который вы написали для конфигураций веб-безопасности, введите эту строку httpSecury.cors();
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors(); // This enables cors
// Your codes
}
}
Ответ 5
Необходима правильная обработка запроса перед полетом OPTIONS, но НЕ ДОСТАТОЧНО для работы запросов на межсайтовые ресурсы.
После того, как запрос OPTIONS возвращается с удовлетворительными заголовками, все ответы на любые последующие запросы на один и тот же URL также должны иметь необходимый заголовок "Access-Control-Allow-Origin", иначе браузер проглотит их, и они выиграли даже не отображается в окне отладчика.
fooobar.com/questions/404319/...
Ответ 6
Текущий рекомендуемый способ делать CORS
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(true).maxAge(3600);
// Add more mappings...
}
}
Это основано на https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors
Но вам также нужно убедиться, что CORS включен и CSRF отключен в вашем файле WebSecurityConfig.
Однажды у меня возникла проблема, когда все мои методы POST не работают (возвращая 403 запрещение), в то время как методы GET работают нормально, но это решается после отключения CSRF
Ответ 7
если использовать подпружиненную загрузку 2, приведенный ниже код достаточен для решения проблемы cors и предполетной проверки
@Override
public void configure(WebSecurity web) throws Exception {
// web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
web.ignoring().antMatchers("/resources/**", "/index.html", "/login.html", "/partials/**", "/template/**", "/",
"/error/**", "/h2-console", "*/h2-console/*");
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
config.setAllowCredentials(true);// this line is important it sends only specified domain instead of *
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
Ответ 8
Это работает для меня
@Configuration
public class CorsConfig implements WebMvcConfigurer {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS");
}
}