我有一个Spring Boot / Spring Data REST服务,允许访问许多资源。其中一些资源(例如/detections
)可以自由访问,其他(例如/users
)需要基本的HTTP身份验证。通过使用CURL测试REST服务,一切都按预期工作。当我尝试从Angular2 Web应用程序访问服务时出现问题。
在这种情况下,访问不受保护的资源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);
}
}
答案 0 :(得分:3)
请参阅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;
}
}
答案 1 :(得分:2)
您可以在第一个Spring Security Filter(即ChannelProcessingFilter)之前添加cors过滤器。以下代码将有助于解释更多。
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/。 注意 - :我是帖子的作者。