2016-11-03 4 views
0

여러 리소스에 액세스 할 수있는 스프링 부트/스프링 데이터 REST 서비스가 있습니다. 이 리소스 중 일부 (예 : /detections)는 자유롭게 액세스 할 수 있으며 다른 리소스 (예 : /users)에는 기본 HTTP 인증이 필요합니다. CURL로 REST 서비스를 테스트하면 모든 것이 예상대로 작동합니다. 문제는 Angular2 웹 응용 프로그램에서 서비스에 액세스하려고 할 때 발생합니다. 보호되지 않은 자원 http://api.mydomain.com/detections에 액세스 할 때이 경우CORS 프리 플라이트 요청 (Spring 데이터 REST) ​​

나는 아무 문제가 없다 :

this.http.get(this.DETECTIONS_API_ENDPOINT).subscribe(
          response => { 
           ... 
          }, 
          error => { 
           ... 
          } 
        ); 

을하지만 올바른 사용자 이름과 암호를 사용하여 필요한 헤더를 전달하여 보호 자원 http://api.mydomain.com/users에 액세스하려고하는 경우 :

let headers = new Headers(); 
    headers.append('Content-Type', 'application/json'); 
    headers.append('Authorization', 'Basic ' + btoa(username+':'+password)); 

    return this.http.get(this.USERS_API_ENDPOINT, { body: "", headers: headers }).subscribe(
          response => { 
           ... 
          }, 
          error => { 
           ... 
          } 
        ); 

(Firefox 콘솔에서) cross-origin request blocked... Reason: CORS preflight request unsuccessfull이라는 오류가 표시됩니다 (이탈리아어에서 번역 한 내용이므로 영어로 정확한 오류 메시지를 찾을 수 없습니다). 두 호출의 차이는 GET 요청 대신 OPTIONS의 전송을 트리거하는 두 번째 경우의 헤더 전달 인 것 같습니다.

내 봄 보안 구성입니다 :

@Configuration 
public class MyAppConfigurationSecurity extends WebSecurityConfigurerAdapter { 

    private Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder(); 

    @Autowired 
    private UserDetailsService myAppUserService; 

    /** 
    * HttpSecurity URL configuration settings. Configure authentication necessary for POST but not for GET 
    */ 

    @Override 
    protected void configure(HttpSecurity http) throws Exception 
    { 
     http.csrf().disable() 
      .authorizeRequests() 
       .antMatchers(HttpMethod.GET, "/detections").permitAll() 
       .antMatchers(HttpMethod.GET, "/detections/search/findTop5ByOrderByTimestampDesc").permitAll() 
       .antMatchers("/users").hasAuthority("ADMIN") 
       .antMatchers("/roles").hasAuthority("ADMIN") 
       .antMatchers("**").authenticated() 
      .and().httpBasic().and() 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 
    } 


    /** 
    * Sets custom MyAppUserService bean as user detail service 
    */ 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(myAppUserService).passwordEncoder(md5PasswordEncoder); 
    } 

} 

이것은 CORS 필터 구성입니다; Spring Data Rest and Cors의 제안에 따라이 클래스를 추가했으며 처음에는 비보호 자원에 액세스하기 위해 CORS 액세스 문제를 해결했습니다. 불행하게도 보호 된 리소스의 경우에는 작동하지 않습니다

@Configuration 
public class MyAppConfigurationCors { 

    @Bean 
    public CorsFilter corsFilter() { 

     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     CorsConfiguration config = new CorsConfiguration(); 
     config.setAllowCredentials(true); // you USUALLY want this 
     config.addAllowedOrigin("*"); 
     config.addAllowedHeader("*"); 
     config.addAllowedMethod("GET"); 
     config.addAllowedMethod("OPTIONS"); // I added this in a second phase, but nothing changes 
     source.registerCorsConfiguration("/**", config); 
     return new CorsFilter(source); 
    } 
} 
+0

이 링크를 확인하십시오. http://stackoverflow.com/a/40374505/4793153 – Eswar

+0

이것이 어떻게 작동해야하는지 명확하지 않습니다. Question my text와 같이 MyAppConfigurationCors 구성 클래스를 Filter 구성 요소로 대체하려고했습니다. , 다음에'if ("OPTIONS"...'테스트를'doFilter' 메쏘드에 넣으려고했으나, 올바르게하고 있는지 확실하지 않습니다. 어떤 경우에도 여전히 오류가 있습니다 ... – chrx

답변

2

CORS and Spring Security를 통합하는 방법에 대한 설명서 봄을 참조하시기 바랍니다.

CORS 먼저 처리되어야합니다 : 첫 번째 봄 보안 즉 ChannelProcessingFilter 필터 전에

@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      // by default uses a Bean by the name of corsConfigurationSource 
      .cors().and() 
      ... 
    } 

    @Bean 
    CorsConfigurationSource corsConfigurationSource() { 
     CorsConfiguration configuration = new CorsConfiguration(); 
     configuration.setAllowedOrigins(Arrays.asList("https://example.com")); 
     configuration.setAllowedMethods(Arrays.asList("GET","POST")); 
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     source.registerCorsConfiguration("/**", configuration); 
     return source; 
    } 
} 
1

당신이 (가) 고르 필터를 추가 할 수 있습니다. 다음 코드는 더 자세한 설명을 돕습니다. 다른 정보는 방문이 필요한 경우

protected void configure(HttpSecurity http) throws Exception { 
http.requiresChannel().antMatchers("/*").requires(ANY_CHANNEL).and() 
.authorizeRequests().antMatchers("/api/customer/**").permitAll() 
.antMatchers("/api/signin").permitAll() 
.antMatchers("/api/**").permitAll() 
.antMatchers("/**").permitAll().and() 
.addFilterBefore(corsFilter(), ChannelProcessingFilter.class) 
.and().csrf().disable(); 
} 

- : http://javamusings.com/enabling-cors-support-in-spring-framework/. 참고 : - 나는 해당 게시물의 저자입니다.

관련 문제