Отключить Spring Безопасность для метода Http OPTIONS

Можно ли отключить Spring Безопасность для типа HTTP-метода?

У нас есть приложение Spring REST с сервисами, для которых требуется токен авторизации в заголовке HTTP-запроса. Я пишу JS-клиент для этого и используя JQuery для отправки запросов GET/POST. Приложение CORS включено с этим кодом фильтра.

doFilter(....) {

  HttpServletResponse httpResp = (HttpServletResponse) response;
  httpResp.setHeader("Access-Control-Allow-Origin", "*");
  httpResp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
  httpResp.setHeader("Access-Control-Max-Age", "3600");
  Enumeration<String> headersEnum = ((HttpServletRequest) request).getHeaders("Access-Control-Request-Headers");
  StringBuilder headers = new StringBuilder();
  String delim = "";
  while (headersEnum.hasMoreElements()) {
    headers.append(delim).append(headersEnum.nextElement());
    delim = ", ";
  }
  httpResp.setHeader("Access-Control-Allow-Headers", headers.toString());
}

Но когда JQuery отправляет запрос OPTIONS для CORS, сервер отвечает отказом авторизации с ошибкой. Очевидно, что запрос OPTIONS не имеет токена авторизации. Так можно ли позволить OPTIONS выйти из уровня безопасности из Spring Конфигурация безопасности?

Ответ 1

Вы пробовали это

Вы можете использовать несколько элементов для определения разных требования к доступу для разных наборов URL-адресов, но они будут оценивается в указанном порядке и будет использоваться первое совпадение. Так что вы должен поставить наиболее конкретные совпадения вверху. Вы также можете добавить метод, чтобы ограничить соответствие конкретному HTTP-методу (GET, POST, PUT и т.д.).

<http auto-config="true">
    <intercept-url pattern="/client/edit" access="isAuthenticated" method="GET" />
    <intercept-url pattern="/client/edit" access="hasRole('EDITOR')" method="POST" />
</http>

Выше означает, что вам нужно выбрать шаблон url для перехвата и какие методы вы хотите

Ответ 2

Если вы используете файл конфигурации безопасности на основе аннотаций (@EnableWebSecurity & @Configuration), вы можете сделать что-то подобное в методе configure() чтобы разрешить запросы OPTION в Spring Security без аутентификации для заданного пути:

@Override
protected void configure(HttpSecurity http) throws Exception
{
     http
    .csrf().disable()
    .authorizeRequests()
      .antMatchers(HttpMethod.OPTIONS,"/path/to/allow").permitAll()//allow CORS option calls
      .antMatchers("/resources/**").permitAll()
      .anyRequest().authenticated()
    .and()
    .formLogin()
    .and()
    .httpBasic();
}

Ответ 3

Разрешить все ОПЦИИ в контексте:

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }

Ответ 4

Если кто-то ищет легкое решение, используя Spring Boot. Просто добавьте дополнительный bean:

   @Bean
   public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() {
      return configurer -> {
         List<RequestMatcher> matchers = new ArrayList<>();
         matchers.add(new AntPathRequestMatcher("/**", "OPTIONS"));
         configurer.requestMatchers(new OrRequestMatcher(matchers));
      };
   }

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

Открытая проблема для лучшего решения: https://github.com/spring-projects/spring-security/issues/4448