Spring Data REST中的CORS预检请求

时间:2016-11-03 15:45:53

标签: authentication angular spring-boot cors spring-data-rest

我有一个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);
    }
}

2 个答案:

答案 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/。 注意 - :我是帖子的作者。