Отключить 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