Idealisan

全面解决springboot应用程序CORS问题

向工程中添加下面这样一个类即可。

package com.example.corsdemo.filter;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@WebFilter
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpRespo = (HttpServletResponse) response;
        HttpServletRequest req= (HttpServletRequest) request;
        httpRespo.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
        httpRespo.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT, CONNECT, TRACE, PATCH");
        httpRespo.setHeader("Access-Control-Max-Age", "3600");
        httpRespo.setHeader("Access-Control-Allow-Credentials", "true");
        httpRespo.setHeader("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,auth-token");
        chain.doFilter(request, response);
    }
}

网上其他解决方案的缺陷分别如下。

  • 在controller类或者方法上使用注解@CorssOrigin:对于整个工程都希望解除CORS限制的时候不够方便,而且不能应对Origin为通配符的时候无法使用cookie的问题。
  • 使用HttpSercurity配置:不能应对Origin为通配符的时候无法使用cookie的问题。
  • 使用WebMvcConfigrationAdaper:过时的方法,并且也不能应对Origin为通配符的时候无法使用cookie的问题。
  • 使用CorsConfiguration对象:不能应对Origin为通配符的时候无法使用cookie的问题。

注意到,问题不仅仅是运输跨域请求,而且要允许带cookie的跨域请求,那么只能使用动态的Access-Control-Allow-Origin响应头。将该响应头针对性的、动态的设置为每一个请求的Origin才行。

分类

讨论 全面解决springboot应用程序CORS问题

  1. idealisan idealisan说道:

    如果使用了Spring Security,那么上面的代码会有冲突,改成使用security添加filter,注意添加filter的顺序。security的代码如下:

    
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.web.access.channel.ChannelProcessingFilter;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors()
                    .and()
                    .addFilterBefore(
                            new Filter() {
                                @Override
                                public void doFilter(
                                        ServletRequest request,
                                        ServletResponse response,
                                        FilterChain chain)
                                        throws IOException, ServletException {
                                    System.out.println("GOGOGOG\n\n\n\n\n\n");
                                    HttpServletResponse httpResp = (HttpServletResponse) response;
                                    HttpServletRequest req = (HttpServletRequest) request;
                                    httpResp.setHeader(
                                            "Access-Control-Allow-Origin", req.getHeader("Origin"));
                                    httpResp.setHeader(
                                            "Access-Control-Allow-Methods",
                                            "POST, GET, OPTIONS, DELETE, HEAD, PUT, CONNECT, TRACE, PATCH");
                                    httpResp.setHeader("Access-Control-Max-Age", "3600");
                                    httpResp.setHeader("Access-Control-Allow-Credentials", "true");
                                    httpResp.setHeader(
                                            "Access-Control-Allow-Headers",
                                            "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,auth-token");
                                    chain.doFilter(request, response);
                                }
                            },
                            ChannelProcessingFilter.class);
        }
    }
    
    

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注