Java Spring Boot-CORS筛选器适用于GET,但不适用于其他HTTP谓词

Java Spring Boot-CORS筛选器适用于GET,但不适用于其他HTTP谓词,java,angular,spring,spring-boot,cors,Java,Angular,Spring,Spring Boot,Cors,我在一个Spring Boot 2.2.5应用程序中工作,该应用程序的前端为Angular 9 我一直在尝试在Spring Boot后端配置CORS过滤器,以允许任何源站对任何请求使用任何头 根据我的研究,我目前在我的主应用程序.java文件中实现的应该可以工作: @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSour

我在一个Spring Boot 2.2.5应用程序中工作,该应用程序的前端为Angular 9

我一直在尝试在Spring Boot后端配置CORS过滤器,以允许任何源站对任何请求使用任何头

根据我的研究,我目前在我的主
应用程序.java
文件中实现的应该可以工作:

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("DELETE");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}
然而,我所经历的是,这只允许我执行从前端到后端控制器的
GET
调用。对
POST
PUT
的任何其他调用失败,并出现以下错误:

Access to XMLHttpRequest at 'http://localhost:8080/spring-boot-starter-seed/default-theme/save/cyan' from origin 'http://localhost:8083' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我知道我的思路是正确的,因为如果我删除了我实现的
@Bean
,那么从前端到后端的所有调用都会因为这个错误而失败。但在实现该Bean时,出于某种原因,它只适用于
GET
请求

我错过了什么吗

*****更新*****

我不知道这是否有帮助,但是,我正在使用Azure AD对此应用程序进行身份验证。我有一个
WebSecurityConfig
如下所示:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
        grantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
        grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");

        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
        return jwtAuthenticationConverter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/actuator/**", "/heartbeat/**", "/register", "/unregister").permitAll()
                .anyRequest().authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt()
                .jwtAuthenticationConverter(this.jwtAuthenticationConverter());
    }
}
在我之前的帖子中,我说
GET
请求正在工作,但这似乎有点错误

GET/heartbeat
有效。然而

GET/default-theme
不起作用,并且由于相同的“无访问控制允许原点”错误而失败

这两个控制器路径之间的唯一区别是,
/default主题
不包含在排除的AntMatcher中,它受
@PreAuthorize(value=“hasRole('ROLE\u access')”)保护

我认为这里的问题是由于dispatcher servlet的过滤器造成的: 还可以尝试使用此类实现筛选器:

public class CORSFilter extends GenericFilterBean implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chaine)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse)response;
        httpResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpResponse.setHeader("Access-Control-Allow-Methods", "*");
        httpResponse.setHeader("Access-Control-Allow-Headers", "*");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "false");
        httpResponse.setHeader("Access-Control-Max-Age", "3600");
        System.out.println("****************** CORS Configuration Completed *******************");
        chaine.doFilter(request, response);
    }

}
然后将bean注入主应用程序类或每个位置:

@Bean
    public FilterRegistrationBean crosFilterRegistration(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new CORSFilter());
        registrationBean.setName("CORS Filter");
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

希望这将是有益的

,因此,事实证明,我对原始帖子的更新是正确的,可以认为Spring安全性和我的
WebSecurity配置
是原因之一

我在答案上找到了真正的解决办法

我需要更新我的
HttpSecurity
配置,首先包括
.cors()

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and()
            .authorizeRequests()
            .antMatchers("/actuator/**", "/heartbeat", "/register", "/unregister").permitAll()
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt()
            .jwtAuthenticationConverter(this.jwtAuthenticationConverter());
}
执行此操作后,所有其他CORS配置都是不必要的,可以从我的应用程序中删除。只需将
@CrossOrigin
注释添加到任何相关控制器。

有了它,调用我的
GET/default主题
控制器,受
@PreAuthorize(value=“hasRole('ROLE\u access')”)
保护,摆脱了无访问控制允许源错误,并导致了我预期的错误,这是一个401响应

所有这些的根本原因是,我的任务是将此应用程序从LDAP auth迁移到Azure AD auth


希望这将对将来的人有所帮助。

WebSecurityConfig
类中,您需要配置
cors
,如下所示

@覆盖
受保护的无效配置(HttpSecurity http)引发异常{
http
...
.及()
.cors().configurationSource(corsConfigurationSource())
.及()
...
}
@Bean
公共公司配置源公司配置源(){
CorsConfiguration配置=新的CorsConfiguration();
configuration.setAllowedOriginates(Arrays.asList(
“此处的域列表”
)
);
setAllowedMethods(Arrays.asList(“DELETE”、“GET”、“POST”、“PATCH”、“PUT”、“OPTIONS”));
配置.setAllowCredentials(true);
configuration.setAllowedHeaders(
Arrays.asList(
“访问控制允许标头”,
“访问控制允许来源”,
“访问控制请求方法”,
“访问控制请求头”,
“来源”,“缓存控制”,
“内容类型”,
“授权”);
UrlBasedCorsConfigurationSource=新的UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(“/**”,配置);
返回源;
}

Amanoun,我尝试了你提供的,但结果是一样的。我已经用更多的信息更新了我的帖子。