Spring security Chrome、Safary、Opera上的飞行前请求失败
我在Springsecurity backen项目+Angulajs前端上与CORS请求进行斗争。 CORS请求在IE上运行良好(同样适用于curl、wget和python请求),但在Chrome和Safary上由于飞行前的错误请求而失败。 我知道那些浏览器正在阻止CORS发布,一旦请求到达后端,请求就会变为空,事实上,当我从后端注销请求时,我看不到任何数据。我尝试了以下所有可能的组合: 前端侧: 1) $http(方法:POST) 2) $http.post( 3) 添加标志:访问控制允许来源、访问控制公开等 4) 添加所有可能的标题组合:“内容–类型”:“应用程序”/ 浏览器端: 1) 使用标志启动chrome:--禁用web安全 2) 安装镀铬加长杆 后端端: 1) 弹簧安全禁用csfr 2) 春季安全许可证 3) Spring安全性HttpMethod.OPTION 4) 设置接受所有来源的CORS筛选器:“*” 5) 已激活用于spring扩展WebMVCConfigureAdapter类的CORS框架 什么都没有,NHOTING为我工作强> 我在另一篇文章中讨论了这个问题: 我仍然无法执行CORS请求,这是我现在的主要问题,我怀疑问题出在LoginFilter中:Spring security Chrome、Safary、Opera上的飞行前请求失败,spring-security,cors,Spring Security,Cors,我在Springsecurity backen项目+Angulajs前端上与CORS请求进行斗争。 CORS请求在IE上运行良好(同样适用于curl、wget和python请求),但在Chrome和Safary上由于飞行前的错误请求而失败。 我知道那些浏览器正在阻止CORS发布,一旦请求到达后端,请求就会变为空,事实上,当我从后端注销请求时,我看不到任何数据。我尝试了以下所有可能的组合: 前端侧: 1) $http(方法:POST) 2) $http.post( 3) 添加标志:访问控制允许来源
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(String url, AuthenticationManager
authenticationManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
try {
ServletInputStream inputStream = httpServletRequest.getInputStream();
httpServletRequest.getCharacterEncoding();
AccountCredentials credentials = null;
ObjectMapper mapper = new ObjectMapper();
credentials = mapper.readValue(inputStream, AccountCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
} catch (JsonMappingException e) {
e.printStackTrace();
throw e;
} catch (JsonParseException e) {
e.printStackTrace();
throw e;
} catch (AuthenticationException e) {
e.printStackTrace();
throw e;
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
AccountCredentials cred = (AccountCredentials) authentication.getPrincipal();
tokenAuthenticationService.addAuthentication(response, cred);
}
}
编辑
Google Chrome上的确切错误是:
:8000/#!/login:1 XMLHttpRequest cannot load http://localhost:8080/myApp/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 403.
在发送实际请求之前,浏览器本身会使用动词选项自动发送飞行前请求。 您必须将服务器配置为在发送此飞行前请求时发送带有某些标头的响应。使用spring security,您可以使用:
@Provider
@Component
public class CrossDomainContainerResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext) throws IOException {
containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "YOUR FRONTEND URI");
containerResponseContext.getHeaders().add("Access-Control-Allow-Headers",
"Access-Control-Allow-Origin");
containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
如果您使用的是XML配置,还可以使用
标记
在Chrome上,禁用web安全对我来说从来都不起作用。但是它在Vivaldi浏览器上工作。因此我发现它与请求头没有任何关系,但问题是响应头 要使飞行前通过,必须映射所有响应头,例如:
response.addHeader("Access-Control-Expose-Headers", "xsrf-token, Authorization, Barer, Token");
(1) 用于编辑/更新您的问题,以添加您的浏览器正在为失败的飞行前记录的确切CORS错误消息。(2) 删除您添加的任何前端代码,这些代码会导致将任何访问控制-*头添加到请求中。这些a访问控制-*都是响应头,应该只在请求发送到的服务器上设置。(3) 删除Chrome扩展CORS,不要从-禁用web安全开始。这些都会妨碍这里的任何人帮助您进行故障排除。您是否控制跨源请求发送到的服务器?如果您不这样做,那么就没有任何可以更改的内容允许前端JavaScript代码访问响应。(您提到您正在使用Spring后端,但从您的问题来看,不清楚这是发送请求的web应用的后端,还是您的代码发送跨源请求的站点的后端。)您好,我正在实施两个项目,在端口8080上运行SpringBoot的后端和在端口8000上运行静态http服务器的前端npm bower,都是在我的本地mashine上设置的,都是在域localhostYes man上我知道这就是为什么我将选项allow origins设置为“*”,协议不是可选的,将http://放在localhost之前。抱歉,man但是ContainerResponseContext类没有addHeaders()方法是的,它是ContainerResponseContext.getHeaders().add(…)。不幸的是,请求甚至没有通过筛选器,我必须将筛选器添加到http.config吗?