У меня есть служба REST службы Spring Boot/Spring, позволяющая получить доступ к ряду ресурсов. Некоторые из этих ресурсов (например, /detections
) свободно доступны, другие (например, /users
) требуют базового HTTP-аутентификации. При тестировании службы REST с CURL все работает так, как ожидалось. Проблемы возникают, когда я пытаюсь получить доступ к сервису из веб-приложения Angular2.Запрос предварительной проверки CORS в Spring Data REST
В этом случае у меня нет никаких проблем при доступе к незащищенным ресурсам http://api.mydomain.com/detections
:
this.http.get(this.DETECTIONS_API_ENDPOINT).subscribe(
response => {
...
},
error => {
...
}
);
Но если я пытаюсь получить доступ к защищенному ресурсу http://api.mydomain.com/users
, передавая необходимые заголовки с правильным именем пользователя и паролем:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Basic ' + btoa(username+':'+password));
return this.http.get(this.USERS_API_ENDPOINT, { body: "", headers: headers }).subscribe(
response => {
...
},
error => {
...
}
);
Я получаю (в консоли Firefox) ошибку, которая говорит cross-origin request blocked... Reason: CORS preflight request unsuccessfull
(обратите внимание, что это мой перевод с итальянского языка. Я не смог найти точное соответствующее сообщение об ошибке на английском языке. Разница между двумя вызовами, по-видимому, заключается в прохождении заголовков во втором случае, что вызывает отправку OPTIONS
вместо запроса GET
.
Это моя конфигурация пружины безопасности:
@Configuration
public class MyAppConfigurationSecurity extends WebSecurityConfigurerAdapter {
private Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
@Autowired
private UserDetailsService myAppUserService;
/**
* HttpSecurity URL configuration settings. Configure authentication necessary for POST but not for GET
*/
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/detections").permitAll()
.antMatchers(HttpMethod.GET, "/detections/search/findTop5ByOrderByTimestampDesc").permitAll()
.antMatchers("/users").hasAuthority("ADMIN")
.antMatchers("/roles").hasAuthority("ADMIN")
.antMatchers("**").authenticated()
.and().httpBasic().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
/**
* Sets custom MyAppUserService bean as user detail service
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myAppUserService).passwordEncoder(md5PasswordEncoder);
}
}
Это конфигурация CORS фильтра; Я добавил этот класс по предложению в Spring Data Rest and Cors, и сначала он решил проблему доступа к CORS для доступа к незащищенным ресурсам. К сожалению, это не похоже на работу в случае защищаемого ресурса:
@Configuration
public class MyAppConfigurationCors {
@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("GET");
config.addAllowedMethod("OPTIONS"); // I added this in a second phase, but nothing changes
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
проверить эту ссылку http://stackoverflow.com/a/40374505/4793153 – Eswar
Мне не очень понятно, как это должно работать: я попытался заменить свой класс конфигурации MyAppConfigurationCors'ом компонентом Filter, как в тексте вопроса , затем попытался поместить тест 'if (" OPTIONS "...' в метод 'doFilter', но я не уверен, что делаю все правильно. В любом случае у меня все еще есть ошибка ... – chrx