Spring Boot:CORS 问题
Posted
技术标签:
【中文标题】Spring Boot:CORS 问题【英文标题】:Spring Boot : CORS Issue 【发布时间】:2019-01-14 03:17:22 【问题描述】:我正在使用 Spring Boot 版本 2.0.2Release。 以下是我的安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
@ComponentScan("com.mk")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private AuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable();
http.cors().configurationSource(corsConfigurationSource())
.and()
.csrf().disable()
.anonymous().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/index.html").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.antMatchers(HttpMethod.GET,"*").authenticated()
.and().httpBasic();
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
由于 CORS 问题,我无法调用任何 API(包括登录 permitAll)。
在我得到的浏览器上(它适用于 Postman,因为那里没有进行 CORS 检查)
无法加载http://localhost:8080/myurl:对预检的响应 请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:4200” 使用权。响应的 HTTP 状态代码为 403。
【问题讨论】:
【参考方案1】:虽然 Spring security 提供了一种在 http 配置器中配置 CORS 的方法,但是有一种更简洁的方法可以将 CORS 过滤器添加到应用程序中——
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCORSFilter implements Filter
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
@Override
public void init(FilterConfig filterConfig)
@Override
public void destroy()
以最高优先级排序过滤器可确保 javax.servlet.Filter
的 MyCORSFilter 实现是链中的第一个。希望这会有所帮助
【讨论】:
这个对我有用。唯一的问题是它在同一个请求中被多次调用。 除了您的 api 调用之外,浏览器发出的每个请求都会调用它。例如。 CSS、图标、图像等 不是 css/icons 等,因为它们托管在不同的服务器上,但让我检查一下 @MohitKanwar 尝试使用 OncePerRequestFilter ,公共类 CustomFIlter 扩展了 OncePerRequestFilter 这对我不起作用,但确实如此:***.com/a/36821971/8092044【参考方案2】:从 Spring 中查看本指南:
https://spring.io/guides/gs/rest-service-cors/
在 Spring Boot 中添加 CORS 支持的方法很少。
使用全局配置:
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
;
并使用@CrossOrigin
注解:
@CrossOrigin(origins = "http://localhost:9000")
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name)
System.out.println("==== in greeting ====");
return new Greeting(counter.incrementAndGet(), String.format(template, name));
【讨论】:
【参考方案3】:无需添加任何额外的Filters
或WebMvcConfigurer
。主要问题是 'Access-Control-Allow-Origin'
没有出现在标头中,因为 corsConfigurationSource
没有添加必要的配置来获取相关的 CORS 响应标头。因此,我们在配置CorsConfigurationSource
时必须添加以下缺少的配置
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
我们必须如下配置cors CorsConfigurationSource
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.cors().configurationSource(corsConfigurationSource())
.and()
.....
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setAllowCredentials(true);
//the below three lines will add the relevant CORS response headers
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
如果有以下组合时遇到CORS
Spring Boot 2.4.0 plus 版本的问题,请参考answer
CorsConfigurationSource#setAllowedOrigins
值为*
和
CorsConfigurationSource#setAllowCredentials
值为true
【讨论】:
你为什么在setAllowedOrigins(Arrays.asList("*"))
之后addAllowedOrigin("*")
?
是的,您可以删除以下addAllowedOrigin("*")
,因为我们已经添加了setAllowedOrigins(Arrays.asList("*"))
,我添加只是为了说明可以添加多个选项来添加来源
但是如果您删除这些重复的行,那么它与 OP 的问题中的代码相同,不是吗?我不明白,我有你说的我的配置,但预检仍然有“No Allow Origin Header”...【参考方案4】:
好的,所以我意识到它已被弃用。如果您查看 baeldung,它会以新的方式进行操作,因为他们更新了 webmvcconfigurer:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*").allowedOrigins(frontDomain);
【讨论】:
你不必使用@EnableWebMvc 我不认为。如果你有,spring boot 不会自动配置 mvc。 另外,如果您要允许所有来源,这就是您的代码所说的,那么 cors 的意义何在。 关于允许所有来源是正确的,这是我用于测试的示例代码。 好的,我猜想是这样的。以上是关于Spring Boot:CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]