2017-04-03 100 views
-1

我在Springsecurity backen项目+ Angulajs前端挣扎着CORS请求。 CORS请求在IE浏览器(也包含curl,wget和python请求)上正常工作,但由于Preflight错误请求,Chrome和Safary发生惨剧。 我知道那些浏览器阻塞了CORS POST,只要到达后端就使请求为空,实际上我从后端注销请求时看不到任何数据。我尝试的每一种可能组合:Chrome,Safary,Opera预检请求失败

前端侧:

1)$ HTTP(方法:POST)

2)$ http.post(

3)添加标记:访问-Control-Allow-Origin,Access-Control-Expose等。

4)添加所有可能的标题组合:'Content-Type':'application/

浏览器侧:

1)开始用标志铬: - 禁用网络的安全

2个)安装浏览器扩展CORS

后端侧:

1) Spring Security Disable csfr

2)Spring Security许可证全部

3)春季安全HttpMethod.OPTION

4)建立接受所有渊源流CORS过滤器:激活CORS框架延伸的弹簧WebMvcConfigurerAdapter类“*”

5)。

没什么,NHOTING为我工作!

我讨论了在另一篇文章这个问题:CORS POST request fails on Chrome, Safari and Firefox I'm仍无法执行请求CORS,这是我现在的主要问题,我怀疑问题是LoginFilter:

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); 
    } 

} 

编辑 在谷歌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. 
+1

(1)使用https://stackoverflow.com/posts/43179530/edit编辑/更新问题以添加浏览器记录失败预检的确切CORS错误消息。 (2)删除已添加的任何前端代码,这会导致将任何Access-Control- *标题添加到请求中。那些Access-Control- *都是*响应*标头,只能在请求发送到的服务器上设置。 (3)删除Chrome扩展CORS,并且不要以-disable-web-security开头。这些只会阻碍任何人在这里帮助您排除故障。 – sideshowbarker

+0

您是否控制了跨源请求被发送到的服务器?如果你不这样做,那么你就没有什么可以改变的,这将允许你的前端JavaScript代码访问响应。 (你提到你使用的是Spring后端,但是从你的问题来看,不清楚这是发送请求的Web应用程序的后端,还是你的代码发送跨源请求的站点的后端。) – sideshowbarker

+0

Hello ,我实施了两个项目,在端口8080上运行SpringBoot的后端和在端口8000上运行静态http服务器的前端npm bower,都在我的本地mashine上进行设置,两者都在本地域主机上 – mattobob

回答

0

所以我发现它没有任何与请求头有关的问题,但问题是响应头。

要通过做飞行前的传球,响应头必须映射,因为例如:

response.addHeader("Access-Control-Expose-Headers", "xsrf-token, Authorization, Barer, Token"); 
-1

预检请求由浏览器,它与动词的选择自动发送在发送真正的请求之前自我。 您必须配置服务器以在发送此预检请求时发送包含某些标头的响应。随着春天的安全性,您可以使用:

@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配置,你也可以使用<cors />标签。

在Chrome上,--disable-web-security从未适用于我。但它在Vivaldi浏览器上工作。

+0

对不起,但ContainerResponseContext类没有addHeaders()方法 – mattobob

+0

是的,它是containerResponseContext.getHeaders()。add(...)。 –

+0

不幸的是,请求甚至没有通过过滤器,我是否必须将过滤器添加到http.config? – mattobob