Java 你能在 Spring 中完全禁用 CORS 支持吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44697883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:41:11  来源:igfitidea点击:

Can you completely disable CORS support in Spring?

javaspringspring-mvcswagger-codegen

提问by baynezy

As described in CORS preflight request fails due to a standard headerif you send requests to OPTIONSendpoints with the Originand Access-Control-Request-Methodheaders set then they get intercepted by the Spring framework, and your method does not get executed. The accepted solution is the use @CrossOriginannotations to stop Spring returning a 403. However, I am generating my API code with Swagger Codegenand so I just want to disable this and implement my OPTIONSresponses manually.

CORS 预检请求中所述,由于标准标头,如果您将请求发送到设置OPTIONSOriginAccess-Control-Request-Method标头的端点,那么它们会被 Spring 框架拦截,并且您的方法不会被执行。接受的解决方案是使用@CrossOrigin注释来阻止 Spring 返回403. 但是,我正在使用Swagger Codegen生成我的 API 代码,所以我只想禁用它并OPTIONS手动实现我的响应。

So can you disable the CORS interception in Spring?

那么可以在Spring中禁用CORS拦截吗?

回答by Yuriy Yunikov

Try to add a following filter (you can customize it for you own needs and methods supported):

尝试添加以下过滤器(您可以根据自己的需要和支持的方法对其进行自定义):

@Component
public class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
                                    final FilterChain filterChain) throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD");
        response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
        response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.addIntHeader("Access-Control-Max-Age", 10);
        filterChain.doFilter(request, response);
    }
}

回答by d0x

From their documentation:

从他们的文档

If you are using Spring Web MVC

如果您使用的是 Spring Web MVC

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

If you are using Spring Boot:

如果您使用的是 Spring Boot:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
            }
        };
    }
}

Yuriy Yunikov answer is correct as well. But I don't like the "custom" filter.

Yuriy Yunikov 的回答也是正确的。但我不喜欢“自定义”过滤器。

In case you have Spring Web Security which causes you trouble. Check thisSO Answer.

如果您有 Spring Web Security,这会给您带来麻烦。检查SO 答案。

回答by Panthro

For newer versions of spring boot:

对于较新版本的 Spring Boot:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedMethods("*");
    }
}

The Kotlin way

Kotlin 方式

@Configuration
class WebConfiguration : WebMvcConfigurer {
    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**").allowedMethods("*")
    }
}

回答by Kirill Ch

I use Spring Security in my Spring Boot application and enable access from specific domains (or from all domains).

我在 Spring Boot 应用程序中使用 Spring Security 并启用从特定域(或所有域)的访问。

My WebSecurityConfig:

我的网络安全配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    // ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // add http.cors()
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers("/get/**").permitAll()
                .antMatchers("/update/**").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .httpBasic(); // Authenticate users with HTTP basic authentication

        // REST is stateless
        http.sessionManagement()
               .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    // To enable CORS
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(ImmutableList.of("https://www.yourdomain.com")); // www - obligatory
//        configuration.setAllowedOrigins(ImmutableList.of("*"));  //set access from all domains
        configuration.setAllowedMethods(ImmutableList.of("GET", "POST", "PUT", "DELETE"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }

}

Sometimes is needed to clear browser history before testing.

有时需要在测试前清除浏览器历史记录。

Detailed information may be seen here: http://appsdeveloperblog.com/crossorigin-restful-web-service/

详细信息可以在这里看到:http: //appsdeveloperblog.com/crossorigin-restful-web-service/



Just for those who use Angular. From Angular I run requests to backend:

仅适用于使用Angular 的人。我从 Angular 向后端运行请求:

export class HttpService {

  username = '..';
  password = '..';
  host = environment.api;
  uriUpdateTank = '/update/tank';

  headers: HttpHeaders = new HttpHeaders({
    'Content-Type': 'application/json',
    Authorization: 'Basic ' + btoa(this.username + ':' + this.password)
  });

  constructor(private http: HttpClient) {
  }

  onInsertTank(tank: Tank) {
    return this.http.put(this.host + this.uriUpdateTank, tank, {
      headers: this.headers
    })
      .pipe(
        catchError(this.handleError)
      );
  }
...
}


Old version.In my Spring Boot application no other ways worked then this:

旧版本。在我的 Spring Boot 应用程序中,没有其他方法可以工作:

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, x-auth-token");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
            try {
                chain.doFilter(req, res);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else {
            System.out.println("Pre-flight");
            response.setHeader("Access-Control-Allowed-Methods", "POST, GET, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "authorization, content-type,x-auth-token, " +
                    "access-control-request-headers, access-control-request-method, accept, origin, authorization, x-requested-with");

            response.setStatus(HttpServletResponse.SC_OK);
        }

    }

    public void init(FilterConfig filterConfig) {
    }

    public void destroy() {
    }

}