Tomcat 8 и Spring Security Cors - PullRequest
       5

Tomcat 8 и Spring Security Cors

2 голосов
/ 31 октября 2019

Я пытаюсь настроить Spring Security, чтобы он поддерживал CORS. Благодаря этому сообщению Spring Security CORS Filter , я заставил его работать на моем локальном хосте с Spring Boot с этим кодом конфигурации:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
        .and()
        .antMatcher("/api/**")
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers(HttpMethod.POST, "/api/login").permitAll()
        .antMatchers(HttpMethod.GET, "/api/websocket/**").permitAll()
        .antMatchers("/api/**").authenticated()
        .and()
        .addFilterBefore(new JWTLoginFilter("/api/login", HttpMethod.POST, authenticationManager(), tokenAuthenticationService, myUserService), UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(new JWTAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class)
        .csrf().disable();
    }

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    final CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(ImmutableList.of("*"));
    configuration.setAllowedMethods(ImmutableList.of("HEAD",
            "GET", "POST", "PUT", "DELETE", "PATCH"));
    // setAllowCredentials(true) is important, otherwise:
    // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
    configuration.setAllowCredentials(true);
    // setAllowedHeaders is important! Without it, OPTIONS preflight request
    // will fail with 403 Invalid CORS request
    configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

}

Нокогда я развертываю свои приложения на удаленных серверах Tomcat, он не работает:

 Access to XMLHttpRequest at 'http://xxx:9080/yyy/api/user/findByLogin/?login=zzz' from origin 'http://xxx:10080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Вот снимок экрана сбойного запроса OPTIONS: enter image description here

Ирабочий запрос на моем локальном хосте: enter image description here

Достаточно ли моего класса конфигурации или мне нужно что-то установить в настройках Tomcat? Спасибо

Ответы [ 7 ]

0 голосов
/ 14 ноября 2019

Просто настройте CorsFilter , чтобы добавить соответствующие заголовки ответа CORS (например, Access-Control-Allow-Origin), используя предоставленный CorsConfigurationSource. Прочитайте его документацию для получения дополнительной информации. Поскольку у вас уже есть UrlBasedCorsConfigurationSource , вы можете настроить фильтр следующим образом:

@Bean
  public FilterRegistrationBean corsFilter() {
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(corsConfigurationSource()));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
  }

Просто укажите вышеупомянутый компонент в вашей конфигурации и, надеюсь, он будет работать.

Вот полный конфиг, в котором вам нужна только часть, как указано выше:

@Bean
  public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    config.addExposedHeader("Content-Disposition");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
  }
0 голосов
/ 14 ноября 2019

Ответ 403 отражает ошибку авторизации. Возможно, ваш сервер настроен на запрос авторизации для запроса параметров. Вы должны убедиться, что параметры настроены на отправку успешного ответа (код состояния 2xx), чтобы позволить браузеру отправлять фактический запрос. Ответ 2xx уведомляет браузер, что сервер обрабатывает запросы CORS.

Причиной того, что ваш запрос работал локально, может быть то, что вы авторизовались, когда сделали запрос. Поэтому проверьте свою аутентификацию, чтобы убедиться, что она правильная. Так как такие запросы перед полетом не отправляют заголовки авторизации, так что вам не следует ожидать на стороне сервера.

0 голосов
/ 13 ноября 2019
  1. Ваши методы разрешения также должны иметь "OPTIONS".
  2. У вас есть веб-сервер? Есть ли вероятность, что на веб-сервере также есть CORS?
0 голосов
/ 12 ноября 2019
  1. Попробуйте поставить точку отладки в методе corsConfigurationSource() в вашем локальном компьютере и проверьте, выполняется ли она. Если он не выполняется, выясните причину - возможно, включив журналы отладки Spring и / или перепроверив конфигурацию Spring.

  2. Также попробуйте добавить OPTIONS в setAllowedMethods

    configuration.setAllowedMethods(ImmutableList.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
    
0 голосов
/ 08 ноября 2019

Проверьте, есть ли на сервере Tomcat конфликтующий фильтр CORS, настроенный в $ CATALINA_BASE / conf / web.xml

0 голосов
/ 07 ноября 2019

Tomcat также имеет свой собственный фильтр cors, и если вы используете другой сервер перед tomcat (например, nodejs, сервер apache vs), проверьте также его фильтры cors.

0 голосов
/ 31 октября 2019

Spring security обеспечивает способ настройки CORS в http configurer, есть гораздо более чистый подход для добавления фильтра CORS в приложение -

@Component 
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCORSFilterClass implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}

Заказ фильтра с наивысшим приоритетом гарантирует, что MyCORSFilterClassimplementation javax.servlet.Filter - первый в цепочке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...