首页 文章

Spring Security CORS过滤器无法正常工作

提问于
浏览
4

我正在使用带有OAuth2(版本:4.0.4.RELEASE)和spring(版本:4.3.1.RELEASE)的spring security .

我'm developing frontend in Angular and I'使用grunt connect:dev(http://127.0.0.1:9000) . 当我尝试通过localhost地址登录时,一切正常,但是从其他地方我收到错误:

“XMLHttpRequest无法加载http://localhost:8084/oauth/token?client_id=MY_CLIENT_ID . 因此不允许对预检请求做出响应't pass access control check: No ' Access-Control-Allow-Origin ' header is present on the requested resource. Origin ' http://127.0.0.1:9000' . 响应的HTTP状态代码为401.”

我在WebMvcConfigurerAdapter中配置了映射(Overrided public void addCorsMappings(CorsRegistry registry))(如下所示),但它仍然不适用于http://127.0.0.1:9000 .

registry.addMapping("/**")
            .allowedOrigins("http://127.0.0.1:9000")
            .allowedMethods("POST", "OPTIONS", "GET", "DELETE", "PUT")
            .allowedHeaders("X-Requested-With,Origin,Content-Type,Accept,Authorization")
            .allowCredentials(true).maxAge(3600);

配置基于:https://spring.io/guides/gs/rest-service-cors/

请指出正确的解决方案来解决这个问题 .

3 回答

  • 9

    希望你很久以前找到答案,但如果没有(如果有其他人发现这个问题像我一样):

    问题是Spring Security使用过滤器运行,这些过滤器通常优先于用户定义的过滤器, @CrossOrigin 和类似的注释等 .

    对我来说有用的是将CORS过滤器定义为具有最高优先级的bean,如建议here .

    @Configuration
    public class MyConfiguration {
    
        @Bean
        public FilterRegistrationBean corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("http://127.0.0.1:9000");
            config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
            config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
            source.registerCorsConfiguration("/**", config);
            FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
            bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
            return bean;
        }
    }
    
  • 0

    很抱歉很长时间的回复 . 我通过配置我的CORS过滤器解决了这个问题,如下所示:

    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class CORSFilter implements Filter {
    
        private static final Logger LOGGER = LogManager.getLogger(CORSFilter.class.getName());
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
            final HttpServletRequest request = (HttpServletRequest) req;
            final HttpServletResponse response = (HttpServletResponse) res;
            final String origin = ((HttpServletRequest) req).getHeader("Origin");
    
            if (ofNullable(origin).isPresent() && origin.equals("http://127.0.0.1:9000")) {
                LOGGER.info("CORSFilter run");
                response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:9000");
                response.addHeader("Access-Control-Allow-Credentials", "true");
    
                if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
                    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                    response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization");
                    response.setStatus(200);
                }
            }
            chain.doFilter(addNessesaryHeaders(request), response);
        }
    
    
        private MutableHttpServletRequest addNessesaryHeaders(final HttpServletRequest request) {
            final MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
            mutableRequest.putHeader("Accept", "application/json");
            mutableRequest.putHeader("Authorization", "Basic" + " bXVzaWNzY2hvb2w6");
            return mutableRequest;
        }
    
        @Override
        public void destroy() {
        }
    }
    
  • 1

    你可以试试这样的东西

    @Configuration
    public class CorsConfig {
       @Bean
       public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
              @Override
              public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods(HttpMethod.OPTIONS.name(),
                                HttpMethod.PATCH.name(),
                                HttpMethod.PUT.name(),
                                HttpMethod.DELETE.name(),
                                HttpMethod.GET.name(),
                                HttpMethod.POST.name())
                        .maxAge(360);
                }
           };
       }
    }
    

    Note: Spring version should be 4.2 or later

相关问题