弹簧安全 CORS 过滤器

Posted

技术标签:

【中文标题】弹簧安全 CORS 过滤器【英文标题】:Spring security CORS Filter 【发布时间】:2017-03-18 00:54:17 【问题描述】:

我们在现有项目中添加了Spring Security

从这一刻起,我们的服务器收到 401 No 'Access-Control-Allow-Origin' header is present on the requested resource 错误。

这是因为响应中没有附加 Access-Control-Allow-Origin 标头。为了解决这个问题,我们在注销过滤器之前的Filter 链中添加了我们自己的过滤器,但该过滤器不适用于我们的请求。

我们的错误:

XMLHttpRequest 无法加载 http://localhost:8080/getKunden。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin http://localhost:3000 不允许访问。响应的 HTTP 状态代码为 401。

我们的安全配置:

@EnableWebSecurity
@Configuration
@ComponentScan("com.company.praktikant")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

@Autowired
private MyFilter filter;

@Override
public void configure(HttpSecurity http) throws Exception 
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();

    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    source.registerCorsConfiguration("/**", config);
    http.addFilterBefore(new MyFilter(), LogoutFilter.class).authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/*").permitAll();


@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 


我们的过滤器

@Component
public class MyFilter extends OncePerRequestFilter 

@Override
public void destroy() 



private String getAllowedDomainsRegex() 
    return "individual / customized Regex";


@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException 

    final String origin = "http://localhost:3000";

    response.addHeader("Access-Control-Allow-Origin", origin);
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers",
            "content-type, x-gwt-module-base, x-gwt-permutation, clientid, longpush");

    filterChain.doFilter(request, response);



我们的应用程序

@SpringBootApplication
public class Application 
public static void main(String[] args) 
    final ApplicationContext ctx = SpringApplication.run(Application.class, args);
    final AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
    annotationConfigApplicationContext.register(CORSConfig.class);
    annotationConfigApplicationContext.refresh();


我们的过滤器是从 spring-boot 注册的:

2016-11-04 09:19:51.494 INFO 9704 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean:将过滤器:“myFilter”映射到:[/*]

我们生成的过滤器链:

2016-11-04 09:19:52.729 INFO 9704 --- [ost-startStop-1] ossweb.DefaultSecurityFilterChain:创建过滤器链:org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5d8c5a8a, org.springframework.security.web.context.SecurityContextPersistenceFilter@7d6938f, org.springframework.security.web.header.HeaderWriterFilter@72aa89c, org.springframework .security.web.csrf.CsrfFilter@4af4df11, com.company.praktikant.MyFilter@5ba65db2, org.springframework.security.web.authentication.logout.LogoutFilter@2330834f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@396532d1 , org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4fc0f1a2, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2357120f, org.springframework.security.web.session.SessionManagementFilter@10867bfb, org.springframework.security.web .access.E xceptionTranslationFilter@4b8bf1fb, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@42063cf1]

回应: Response headers

我们也尝试了 spring 的解决方案,但没有奏效!我们控制器中的注解 @CrossOrigin 也没有帮助。

编辑 1:

尝试了@Piotr Sołtysiak 的解决方案。 cors 过滤器未列在生成的过滤器链中,我们仍然得到相同的错误。

2016-11-04 10:22:49.881 INFO 8820 --- [ost-startStop-1] ossweb.DefaultSecurityFilterChain:创建过滤器链:org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4c191377, org.springframework.security.web.context.SecurityContextPersistenceFilter@28bad32a, org.springframework.security.web.header.HeaderWriterFilter@3c3ec668, org.springframework .security.web.csrf.CsrfFilter@288460dd, org.springframework.security.web.authentication.logout.LogoutFilter@1c9cd096, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@3990c331, org.springframework.security.web.authentication .ui.DefaultLoginPageGeneratingFilter@1e8d4ac1, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@2d61d2a4, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@380d9a9b, org.springframework.security.web.servletapi.SecurityContextHo lderAwareRequestFilter@abf2de3, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2a5c161b, org.springframework.security.web.session.SessionManagementFilter@3c1fd3e5, org.springframework.security.web.access.ExceptionTranslationFilter@3d7055ef, org.springframework。 security.web.access.intercept.FilterSecurityInterceptor@5d27725a]

顺便说一句,我们使用的是 spring-security 版本 4.1.3。!

【问题讨论】:

Chrome 存在问题,它不支持 localhost 通过 Access-Control-Allow-Origin。换个浏览器试试 我们尝试使用 Edge,它可以正常工作...但 Firefox 不能正常工作。 我遇到了同样的问题,我通过将127.0.0.1 localhost local.net 添加到/etc/hosts 然后调用local.net:8080/getKunden 来解决它 请参阅***.com/questions/28547288/… 它会有所帮助 【参考方案1】:

从 Spring Security 4.1 开始,这是使 Spring Security 支持 CORS 的正确方法(Spring Boot 1.4/1.5 也需要):

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    

和:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
//        http.csrf().disable();
        http.cors();
    

    @Bean
    public CorsConfigurationSource corsConfigurationSource() 
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

不要不要做以下任何一种尝试解决问题的错误方法:

http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll(); web.ignoring().antMatchers(HttpMethod.OPTIONS);

参考:http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html

【讨论】:

如果你不使用 Guava,你可以随时这样做:Collections.unmodifiableList(Arrays.asList("HEAD",...)) 请注意,WebMvcConfigurerAdapter 现在已被弃用。 不要在不知道自己在做什么的情况下删除 CSRF! owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) 仍然无法使用此解决方案,导致预检请求被阻止。 WebMvcConfigurerAdapter 类型已弃用。从 Spring 5 开始你只需要实现接口WebMvcConfigurer【参考方案2】:

由于我在使用其他解决方案时遇到了问题(特别是为了让它在所有浏览器中都能正常工作,例如 edge 无法将“*”识别为“Access-Control-Allow-Methods”的有效值),我不得不使用自定义过滤器组件,它最终对我有用,并且完全符合我的要求。

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods",
                "ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, Key, Authorization");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) 
            response.setStatus(HttpServletResponse.SC_OK);
         else 
            chain.doFilter(req, res);
        
    

    public void init(FilterConfig filterConfig) 
        // not needed
    

    public void destroy() 
        //not needed
    


【讨论】:

这里也一样。不过必须用 X-Authorization 替换 Authorization。 我为什么选择这个解决方案:因为我有 AuthorizationFilter 它在 CorsBean 之前响应,因此所有 Cors 预检请求都由 AuthFilter 响应,而不是 Spring Cors 配置。因此我用这个解决方案中提到的 CorsFilter 替换了 CorsConfig bean;现在 Cors 飞行前请求由 CorsFilter 按预期回答。 @大卫谢谢。【参考方案3】:

好的,经过 2 多天的搜索,我们终于解决了这个问题。我们删除了所有过滤器和配置,而是在应用程序类中使用了这 5 行代码。

@SpringBootApplication
public class Application 
    public static void main(String[] args) 
        final ApplicationContext ctx = SpringApplication.run(Application.class, args);
    

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/**").allowedOrigins("http://localhost:3000");
            
        ;
    

【讨论】:

您使用的是什么类型的身份验证?基本,形式?【参考方案4】:

使用 Spring Boot 2 中的 Spring Security 全局配置 CORS(例如启用所有开发请求),您可以:

@Bean
protected CorsConfigurationSource corsConfigurationSource() 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
    return source;


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

【讨论】:

【参考方案5】:

    你不需要:

    @Configuration
    @ComponentScan("com.company.praktikant")
    

    @EnableWebSecurity 里面已经有@Configuration,我无法想象你为什么把@ComponentScan 放在那里。

    关于 CORS 过滤器,我只想说:

    @Bean
    public FilterRegistrationBean corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0); 
        return bean;
    
    

    进入 SecurityConfiguration 类并删除配置和配置全局方法。您不需要设置两次允许的来源、标题和方法。特别是如果您在过滤器和弹簧安全配置中放置不同的属性:)

    根据上述,您的“MyFilter”类是多余的。

    您也可以删除这些:

    final AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
    annotationConfigApplicationContext.register(CORSConfig.class);
    annotationConfigApplicationContext.refresh();
    

    来自应用程序类。

    最后的小建议 - 与问题无关。您不想将动词放在 URI 中。而不是http://localhost:8080/getKunden,您应该在http://localhost:8080/kunden 资源上使用HTTP GET 方法。您可以在此处了解设计 RESTful api 的最佳实践:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

【讨论】:

【参考方案6】:

我生命中的 8 个小时,我再也回不来了……

确保在 CorsConfiguration 中同时设置 Exposed Headers 和 Allowed Headers

@Bean
CorsConfigurationSource corsConfigurationSource() 
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
    configuration.setExposedHeaders(Arrays.asList("Authorization", "content-type"));
    configuration.setAllowedHeaders(Arrays.asList("Authorization", "content-type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;

【讨论】:

【参考方案7】:

在很多地方,我看到需要添加此代码的答案:

@Bean
public FilterRegistrationBean corsFilter() 
   UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
   CorsConfiguration config = new CorsConfiguration();
   config.setAllowCredentials(true);
   config.addAllowedOrigin("*");
   config.addAllowedHeader("*");
   config.addAllowedMethod("*");
   source.registerCorsConfiguration("/**", config);
   FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
   bean.setOrder(0); 
   return bean;

但在我的情况下,它会引发意外的类类型异常。 corsFilter() bean 需要 CorsFilter 类型,所以我已经完成了这些更改并将这个 bean 的定义放入我的配置中,现在一切正常。

@Bean
public CorsFilter corsFilter() 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);

【讨论】:

【参考方案8】:

WebMvcConfigurerAdapter 类从 5.0 开始被弃用。WebMvcConfigurer 具有默认方法,无需此适配器即可直接实现。对于这种情况:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer 
    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**").allowedOrigins("http://localhost:3000");
    


另见:Same-Site flag for session cookie

【讨论】:

【参考方案9】:

根据CORS filter documentation:

"Spring MVC 为 CORS 配置提供了细粒度的支持 通过控制器上的注释。然而 当与 Spring 一起使用时 安全建议依赖内置的 CorsFilter 在 Spring Security 的过滤器链之前订购”

这样的事情将允许GET 访问/ajaxUri

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AjaxCorsFilter extends CorsFilter 
    public AjaxCorsFilter() 
        super(configurationSource());
    

    private static UrlBasedCorsConfigurationSource configurationSource() 
        CorsConfiguration config = new CorsConfiguration();

        // origins
        config.addAllowedOrigin("*");

        // when using ajax: withCredentials: true, we require exact origin match
        config.setAllowCredentials(true);

        // headers
        config.addAllowedHeader("x-requested-with");

        // methods
        config.addAllowedMethod(HttpMethod.OPTIONS);
        config.addAllowedMethod(HttpMethod.GET);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/startAsyncAuthorize", config);
        source.registerCorsConfiguration("/ajaxUri", config);
        return source;
    

当然,您的 SpringSecurity 配置必须允许使用列出的方法访问 URI。请参阅@Hendy Irawan 的回答。

【讨论】:

【参考方案10】:

经过几个小时的研究,这个解决方案解锁了我:

在配置中初始化 core() 选项

@Override
public void configure(HttpSecurity http) throws Exception 
http
    .cors()
    .and()
    .etc

根据您的意愿在 corsFilter 中初始化您的凭据、来源、标头和方法。

@Bean
public CorsFilter corsFilter() 
  UrlBasedCorsConfigurationSource source = new 
  UrlBasedCorsConfigurationSource();
  CorsConfiguration config = new CorsConfiguration();
  config.setAllowCredentials(true);
  config.addAllowedOrigin("*");
  config.addAllowedHeader("*");
  config.addAllowedMethod("*");
  source.registerCorsConfiguration("/**", config);
  return new CorsFilter(source);

我不需要使用这个类:

@Bean
public CorsConfigurationSource corsConfigurationSource() 

【讨论】:

【参考方案11】:

就我而言,我只是添加了这个类并使用@EnableAutConfiguration

@Component
public class SimpleCORSFilter extends GenericFilterBean 
    /**
     * The Logger for this class.
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) throws IOException, ServletException 
        logger.info("> doFilter");

        HttpServletResponse response = (HttpServletResponse) resp;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
        //response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, resp);

        logger.info("< doFilter");
    

【讨论】:

【参考方案12】:

使用 SpringBoot 2 Spring Security,下面的代码完美解决了 Cors 问题

@Bean
public CorsConfigurationSource corsConfigurationSource() 
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Collections.singletonList("*")); // <-- you may change "*"
    configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(Arrays.asList(
            "Accept", "Origin", "Content-Type", "Depth", "User-Agent", "If-Modified-Since,",
            "Cache-Control", "Authorization", "X-Req", "X-File-Size", "X-Requested-With", "X-File-Name"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;


@Bean
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() 
    FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(corsConfigurationSource()));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;

然后对于网络安全配置,我添加了这个

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.headers().frameOptions().disable()
            .and()
            .authorizeRequests()
            .antMatchers("/oauth/tokeen").permitAll()
            .antMatchers(HttpMethod.GET, "/").permitAll()
            .antMatchers(HttpMethod.POST, "/").permitAll()
            .antMatchers(HttpMethod.PUT, "/").permitAll()
            .antMatchers(HttpMethod.DELETE, "/**").permitAll()
            .antMatchers(HttpMethod.OPTIONS, "*").permitAll()
            .anyRequest().authenticated()
            .and().cors().configurationSource(corsConfigurationSource());

【讨论】:

【参考方案13】:

若要在全球范围内启用 CORS,您需要在两个地方进行更改,如果您还使用 spring security with boot:

1.春季启动:

@Configuration
public class CorsConfiguration extends WebMvcConfigurationSupport   
    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("*")
        .allowCredentials(true);
    

你可以在WebMvcConfigurerAdapter中做同样的事情,或者创建WebMvcConfigurer的bean。

2。春季安全

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS).permitAll() //Permits your preflight request

这会启用所有方法、所有路径和来源。因此,请谨慎使用,仅在开发中使用。 在 Spring Boot 2.3.3.RELEASE 上工作

【讨论】:

【参考方案14】:

我遇到了类似的问题,但具体要求是从我们的端点中的装饰器中设置 CORS 标头,如下所示:

@CrossOrigin(origins = "*", allowCredentials = "true")
@PostMapping(value = "/login")

或者

@CrossOrigin(origins = "*")
@GetMapping(value = "/verificationState")

因此,简单地拦截请求、手动设置 CORS 标头并返回 200 不是一种选择,因为在某些情况下需要允许 allowCredentials 为真,并且不允许使用通配符。当然,CORS 注册会有所帮助,但由于我们的客户在 androidios 上的电容器有角,因此没有特定的域可以注册。因此,在我看来,干净的做法是将预检直接通过管道传输到端点以让它们处理它。我用这个解决了它:

@Component
public class PreflightFilter extends OncePerRequestFilter 

    private static final Logger logger = LoggerFactory.getLogger(PreflightFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException 

        if (CorsUtils.isPreFlightRequest(request)) 
            logger.info("Preflight request accepted");
            SecurityContextHolder.getContext().setAuthentication(createPreflightToken(request));
        
        chain.doFilter(request, response);
    

    private UsernamePasswordAuthenticationToken createPreflightToken(HttpServletRequest request) 
        UserDetails userDetails = new User("Preflight", "",
                true, true, true, true,
                Stream.of(new SimpleGrantedAuthority("AppUser")).collect(Collectors.toSet()));
        UsernamePasswordAuthenticationToken preflightToken =
                new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
        preflightToken
                .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        return preflightToken;
    

请记住,端点装饰器在这里的工作方式并不像人们所期望的那样使用通配符!

【讨论】:

【参考方案15】:

这允许任何具有 CORS 凭据的来源:

@Component
public class FilterChainConfig implements Filter 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException 
        if (servletResponse instanceof HttpServletResponse)
            HttpServletResponse response = (HttpServletResponse)servletResponse;
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String requestOrigin = request.getHeader("Origin");
            response.setHeader("Access-Control-Allow-Origin", requestOrigin);
            response.setHeader("Access-Control-Allow-Credentials", "true");
            //response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            filterChain.doFilter(request, response);
        
    

【讨论】:

以上是关于弹簧安全 CORS 过滤器的主要内容,如果未能解决你的问题,请参考以下文章

弹簧安全CORS过滤器

弹簧安全CORS过滤器

弹簧安全CORS过滤器

keycloak CORS 过滤器弹簧靴

用于弹簧靴的 CORS 过滤器不起作用

有没有办法在没有弹簧安全的情况下使用弹簧过滤器链?