2017-04-03 5 views
-1

Springsecurity 백엔드 프로젝트 + Angulajs 프론트 엔드에서 CORS 요청에 어려움을 겪고 있습니다. CORS 요청이 IE (curl, wget 및 python 요청과 함께)에서 제대로 작동하지만 프리 플라이트 불량 요청으로 인해 Chrome 및 Safary에서 비참하게 실패합니다. 그 브라우저가 CORS POST를 차단하고있어 백엔드에 도달하자마자 요청을 비워 둡니다. 실제로 백엔드에서 요청을 로그 아웃 할 때 데이터가 표시되지 않습니다.Chrome, Safary, Opera에서 프리 플라이트 요청이 실패합니다.

프론트 엔드 측 :

1) $ HTTP (방법 : POST)

2) $ http.post (

3) 추가 플래그 : 나는 모든 가능한 조합을 시도 액세스 제어 가능 - 노출 등 -

4) 가능한 모든 헤더 조합 추가 : 'Content-Type': 'application/

브라우저 측 :

1) 플래그 크롬을 시작 --disable-웹 보안

2) 설치 크롬 확장 CORS

백엔드 측 :

1) 스프링 보안 비활성화 csfr

2) 봄 보안 모두 허용

"*"

5) 스프링 확장 WebMvcConfigurerAdapter 클래스 CORS 프레임 워크 활성화 : 1,363,210

3) 봄 보안 HttpMethod.OPTION

4) 모든 기원을 수락 CORS 필터를 설정합니다.

NHOTING은 나를 위해 일했습니다. CORS POST request fails on Chrome, Safari and Firefox 미안 여전히이 지금 큰 문제 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); 
    } 

} 

편집 구글 크롬에 대한 정확한 오류는 다음과 같습니다

: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 *은 요청이 보내지는 서버에만 설정되어야하는 모든 * response * 헤더입니다. (3) Chrome 확장 CORS를 제거하고 -disable-web-security로 시작하지 마십시오. 문제 해결에 도움을 줄 수있는 사람들이 여기에 있습니다. – sideshowbarker

+0

원본 교차 요청이 전송되는 서버를 제어합니까? 그렇지 않으면 프론트 엔드 JavaScript 코드가 응답에 액세스 할 수 있도록 변경할 수있는 것이 없습니다. (당신은 Spring 백엔드를 사용하고 있다고 말하지만 질문에서 요청을 보내는 웹 응용 프로그램의 백엔드인지 여부 또는 코드가 원본 요청을 보내는 사이트의 백엔드인지 여부는 확실하지 않습니다. – sideshowbarker

+0

Hello , 나는 두 프로젝트, 포트 8080에서 SpringBoot를 실행하는 백엔드와 포트 8000에서 정적 http 서버를 실행하는 프론트 엔드 npm bower를 구현합니다. 둘 다 내 로컬 mashine에 설정되어 있습니다. 둘 다 도메인 로컬 호스트에 있습니다. – mattobob

답변

0

그래서 요청 헤더와 관련이 없지만 문제는 응답 헤더입니다.

모든 응답 헤더는 예로서, 매핑 할 필요 통해 프리 플라이트 통과를 만들려면 :

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

프리 플라이트 요청은 브라우저 그것에 의해 동사 옵션을 자동으로 전송됩니다 self는 실제 요구가 보내지기 전에. 이 프리 플라이트 요청을 보낼 때 일부 헤더와 함께 응답을 보내도록 서버를 구성해야합니다. 봄 보안 사용하면 사용할 수 있습니다 : 당신이 XML의 설정을 사용하는 경우, 당신은 또한 <cors /> 태그를 사용할 수 있습니다

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

.

--disable-web-security는 Chrome에서 절대로 작동하지 않습니다. 그러나 Vivaldi Browser에서 작동했습니다.

+0

ContainerResponseContext 클래스에 addHeaders() 메소드가 없습니다. – mattobob

+0

예, containerResponseContext.getHeaders(). add (...)입니다. –

+0

불행히도 요청이 필터를 통과하지 못하더라도 http.config에 필터를 추가해야합니까? – mattobob

관련 문제