Spring boot:无法从另一个Origin访问安全资源 - CORS - Spring Security - Spring数据休息

时间:2018-03-28 12:35:07

标签: rest spring-boot spring-security cors spring-data-rest

我无法从另一个Origin访问安全资源。搜索了几天的解决方案并没有找到它,所以我在这里发布了问题。

这就是故事:

我创建了第一个在默认端口8080上运行的Spring Boot应用程序。

它取决于spring-boot-starter-data-rest和其他依赖项,它有一个GreetingRepository:

public interface GreetingRepository extends JpaRepository<Greeting, Long>, JpaSpecificationExecutor<Greeting> {}

全局启用CORS和RepositoryRestConfigurerAdapter:

@Configuration 
public class GlobalRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter {

@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry()
            .addMapping("/**")
            .allowedOrigins("*")
            .allowedHeaders("*")
            .allowedMethods("*");
}
}

我创建了第二个Spring Boot Application,它运行在端口9000上,可以访问这个Greetings资源。

它有效。第二个应用程序使用方法GET将HTTP请求发送到http://localhost:8080/api/greetings,并使用HEADER Access-Control-Allow-Origin:*获取Json数据的响应。一切都很好。

但是

然后我想在第一个应用程序中保护我的资源。我在其中包含了spring-boot-starter-security依赖项,并在WebSecurityConfigurerAdapter中进行了配置:

@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService myUserDetailsService;

@Autowired
PasswordEncoder myPasswordEncoder;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(myUserDetailsService).passwordEncoder(myPasswordEncoder);
}

@Bean
public UserDetailsService createBeanUserDetailService() {
    return new MyUserDetailsService();
}

@Bean
public PasswordEncoder createBeanPasswordEncoder() {
    return new BCryptPasswordEncoder();
}
}

并制作UserDetailsS​​ervice等。 (重要:我在添加CORS之前测试了安全性,因此这种安全配置有效并且不是问题)。

然后,在第一个应用程序中添加安全性后,第二个应用程序将第一次使用方法GET的相同HTTP请求发送到http://localhost:8080/api/greetings

现在出现错误Failed to load http://localhost:8080/api/greetings: Redirect from 'http://localhost:8080/api/greetings' to 'http://localhost:8080/login' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.

我无法找到解决此问题的方法。因此CORS适用于Spring Repository资源,而Spring Security可以工作,但由于/ login页面,我无法从另一个Origin访问安全资源。怎么解决这个问题?

1 个答案:

答案 0 :(得分:0)

启用Spring安全性后,安全筛选器优先于CorsFilter。要使Spring Security了解您的CORS配置,请在cors()设置中调用HttpSecurity方法。

@Override
protected void configure(HttpSecurity http) throws Exception {
  http
        .cors()
        .and()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .formLogin().permitAll()
        .and()
        .httpBasic()
        .and()
        .csrf().disable();
}

这将使CorsFilter优先于其他Spring安全过滤器。 CorsFilter识别CORS预检请求(HTTP OPTIONS调用)并允许它在没有任何安全性的情况下通过。