2017-04-03 51 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