所以我知道问题是什么,我只是不知道如何修复它。
我正在使用Spring Boot 1.3.3,而CorsFilter的设置如下
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private Environment env;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://192.168.1.132:8100")
.allowedHeaders("Accept", "Content-Type","X-Auth-Token", "Origin", "Pragma","Cache-Control",
"If-Modified-Since","Authorization")
.exposedHeaders("X-Auth-Token")
.allowedMethods("PUT","POST","GET","OPTIONS")
.allowCredentials(true).maxAge(3600);
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/save-user","/test","/error","/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
http.addFilterAfter(new CustomStatelessAuthenticationFilter(tokenAuthenticationService),
UsernamePasswordAuthenticationFilter.class);
...
}
我遇到的问题是我使用类似X-Auth-Token
的自定义令牌来验证用户。但是在CorsRegistry之前调用了CustomStatelessAuthenticationFilter
。在Chrome拨打电话之前,它会进行OPTIONS
调用以确保应用程序合法。它不允许我传递X-AUTH-TOKEN
标题而不验证该呼叫是否合法。所以它不允许我传递X-AUTH-TOKEN
,直到服务器从服务器获得响应状态OK
。好了,因为CustomStatelessAuthenticationFilter
首先调用,X-AUTH-TOKEN
返回null。要解决这个问题,我必须做这样的事情......
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
boolean debug = this.logger.isDebugEnabled();
if(debug) {
this.logger.debug("Custom.Custom Stateless Authentication");
}
if (request.getMethod().equals("OPTIONS")) {
response.addHeader("Access-Control-Allow-Origin", "http://192.168.1.132:8100");
response.addHeader("Access-Control-Allow-Headers", "X-Auth-Token");
response.addHeader("Access-Control-Expose-Headers", "X-Auth-Token");
response.setStatus(HttpServletResponse.SC_OK);
} else {
SecurityContextHolder.getContext().setAuthentication(
this.tokenAuthenticationService.getAuthentication((HttpServletRequest) request));
filterChain.doFilter(request, response);
}
}
换句话说,我必须手动返回状态为OK
的客户端才能发出真实请求。它产生两个请求,一个用于确保OPTION调用返回OK(预先飞行请求),然后它使另一个实际上使用X-Auth-Token
进行调用。我不想这样做,因为它完全无视我的CorsMapping。我想让它在继续之前检查CorsMapping First。那么我应该在哪里正确设置验证,以便它在实际验证之前已经先接受OPTIONS
检查。
我还在安全配置
中尝试了以下内容http.addFilterAfter(new CustomStatelessAuthenticationFilter(tokenAuthenticationService),
CsrfFilter.class);
我建议Upvote,因为我没有找到可靠的解决方案。到目前为止,addCorsMappings
比旧版本中仅添加CorsFilter
的旧解决方案更让我感到痛苦