Spring 数据 REST 中的 CORS 预检请求
CORS preflight request in Spring Data REST
我有一个 Spring Boot / Spring Data REST 服务允许访问许多资源。其中一些资源(例如 /detections
)可以免费访问,其他资源(例如 /users
)需要基本的 HTTP 身份验证。通过使用 CURL 测试 REST 服务,一切都按预期工作。当我尝试从 Angular2 网络应用程序访问服务时出现问题。
在这种情况下,我在访问不受保护的资源时没有问题http://api.mydomain.com/detections
:
this.http.get(this.DETECTIONS_API_ENDPOINT).subscribe(
response => {
...
},
error => {
...
}
);
但是,如果我尝试通过使用正确的用户名和密码传递所需的 headers 来访问受保护的资源 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
(请注意,这是我从意大利语翻译过来的。我找不到准确对应的英文错误消息。唯一的区别是在第二种情况下,两次调用似乎是 headers 的传递,这会触发发送 OPTIONS
而不是 GET
请求。
这是我的 spring 安全配置:
@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过滤器配置;我按照 的建议添加了这个 class,它最初解决了我的 CORS-access 访问未受保护资源的问题。不幸的是,它似乎在受保护资源的情况下不起作用:
@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);
}
}
请参阅Spring文档了解如何集成CORS and Spring Security。
必须先处理 CORS:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors().and()
...
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
您可以在第一个 Spring 安全过滤器之前添加 cors 过滤器,即 ChannelProcessingFilter。下面的一段代码将有助于解释更多。
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().antMatchers("/*").requires(ANY_CHANNEL).and()
.authorizeRequests().antMatchers("/api/customer/**").permitAll()
.antMatchers("/api/signin").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/**").permitAll().and()
.addFilterBefore(corsFilter(), ChannelProcessingFilter.class)
.and().csrf().disable();
}
如果需要任何其他信息,请访问此 -:
http://javamusings.com/enabling-cors-support-in-spring-framework/。
注-:我是post的作者。
我有一个 Spring Boot / Spring Data REST 服务允许访问许多资源。其中一些资源(例如 /detections
)可以免费访问,其他资源(例如 /users
)需要基本的 HTTP 身份验证。通过使用 CURL 测试 REST 服务,一切都按预期工作。当我尝试从 Angular2 网络应用程序访问服务时出现问题。
在这种情况下,我在访问不受保护的资源时没有问题http://api.mydomain.com/detections
:
this.http.get(this.DETECTIONS_API_ENDPOINT).subscribe(
response => {
...
},
error => {
...
}
);
但是,如果我尝试通过使用正确的用户名和密码传递所需的 headers 来访问受保护的资源 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
(请注意,这是我从意大利语翻译过来的。我找不到准确对应的英文错误消息。唯一的区别是在第二种情况下,两次调用似乎是 headers 的传递,这会触发发送 OPTIONS
而不是 GET
请求。
这是我的 spring 安全配置:
@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过滤器配置;我按照
@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);
}
}
请参阅Spring文档了解如何集成CORS and Spring Security。
必须先处理 CORS:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors().and()
...
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
您可以在第一个 Spring 安全过滤器之前添加 cors 过滤器,即 ChannelProcessingFilter。下面的一段代码将有助于解释更多。
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().antMatchers("/*").requires(ANY_CHANNEL).and()
.authorizeRequests().antMatchers("/api/customer/**").permitAll()
.antMatchers("/api/signin").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/**").permitAll().and()
.addFilterBefore(corsFilter(), ChannelProcessingFilter.class)
.and().csrf().disable();
}
如果需要任何其他信息,请访问此 -: http://javamusings.com/enabling-cors-support-in-spring-framework/。 注-:我是post的作者。