弹簧CORS错误
Posted
技术标签:
【中文标题】弹簧CORS错误【英文标题】:Spring CORS error 【发布时间】:2017-12-31 19:27:27 【问题描述】:我正在使用 Spring 构建 WebApi,并使用 Reactjs 构建客户端。我正在尝试针对 WebApi 执行 POST 请求以使用 OAuth2 进行身份验证,但我不断收到
预检响应包含无效的 HTTP 状态代码 401
WebSecurityConfigurerAdapter:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Bean
public CorsFilter corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(false); //updated to false
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/**").authenticated()
.and()
.httpBasic();
我的要求是:
fetch(
this.getAuthEndpoint('password'),
method:'post',
headers:
'Access-Control-Allow-Origin': '*',
'Authorization': 'Basic dG9ucjpzZWNyZXQ='
,
body: JSON.stringify(
'password': credentials.password,
'username': credentials.username,
'grant_type': 'password',
'scope': 'read write',
'client_secret': Config.clientSecret,
'client_id': Config.clientId
))
.then(response =>
this.saveTokens(response.data);
return axios.get(Config.apiUrl + '/me');
)
.then(response =>
this.loginSuccess(response.data.user);
)
.catch(response =>
this.loginError(response);
);
请求/响应状态为:
【问题讨论】:
【参考方案1】:尝试做 http.cors().. 像
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors()....
参考https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
这将添加一个 CORS 过滤器并立即返回,而不是将请求传递给安全过滤器。
【讨论】:
【参考方案2】:如果您使用的是 Springboot,请将以下代码添加到 application.java 中
package com.khan.vaquar;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@SpringBootApplication
public class SpringBootGraphqlApplication
public static void main(String[] args)
SpringApplication.run(SpringBootGraphqlApplication.class, args);
@Bean
public CorsFilter corsFilter()
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Arrays.stream(HttpMethod.values()).map(HttpMethod::name).collect(Collectors.toList()));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
【讨论】:
【参考方案3】:添加一个 CorsFilter
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter
//private final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);
public SimpleCorsFilter()
System.out.println("SimpleCORSFilter init");
@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, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, x-auth-token");
System.out.println("cors filter called");
if ("OPTIONS".equalsIgnoreCase(request.getMethod()))
response.setStatus(HttpServletResponse.SC_OK);
else
chain.doFilter(req, res);
// chain.doFilter(req, res);
@Override
public void init(FilterConfig filterConfig)
@Override
public void destroy()
【讨论】:
以上是关于弹簧CORS错误的主要内容,如果未能解决你的问题,请参考以下文章