2016-04-23 18 views
7

Devo aggiungere il filtro CORS alla mia applicazione web Spring Boot.Spring Boot Filtro CORS - Canale di preflight CORS non riuscito

Ho aggiunto mappature CORS come descritto nella seguente documentazione http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html

Questo è il mio config:

@Configuration 
@EnableWebMvc 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
     // @formatter:off 
     registry 
      .addMapping("/**") 
      .allowedOrigins(CrossOrigin.DEFAULT_ORIGINS) 
      .allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS) 
      .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 
      .maxAge(3600L); 
     // @formatter:on 
    } 

... 

} 

Proprio ora, quando sto cercando di accedere al mio API ho la ricezione di un messaggio di errore:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com/api/v1.0/user. (Reason: CORS preflight channel did not succeed). 

Questo è uno screenshot da console FF:

enter image description here

Cosa sto facendo male e come configurare correttamente le intestazioni CORS per evitare questo problema?

risposta

20

ho fissato questo problema creando un nuovo CORS filtro:

@Component 
public class CorsFilter extends OncePerRequestFilter { 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
     response.setHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 
     response.setHeader("Access-Control-Max-Age", "3600"); 
     response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token"); 
     response.addHeader("Access-Control-Expose-Headers", "xsrf-token"); 
     if ("OPTIONS".equals(request.getMethod())) { 
      response.setStatus(HttpServletResponse.SC_OK); 
     } else { 
      filterChain.doFilter(request, response); 
     } 
    } 
} 

e aggiunto a securty configurazione:

.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class) 

AGGIORNAMENTO - modo più moderno al giorno d'oggi, che sono passato a :

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http 
      .cors() 
     .and() 

     ... 
    } 

    @Bean 
    public CorsConfigurationSource corsConfigurationSource() { 
     CorsConfiguration configuration = new CorsConfiguration(); 
     configuration.setAllowedOrigins(Arrays.asList("*")); 
     configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); 
     configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token")); 
     configuration.setExposedHeaders(Arrays.asList("x-auth-token")); 
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     source.registerCorsConfiguration("/**", configuration); 
     return source; 
    } 

} 
+1

Se si desidera supportare le API RESTful corrette, non si dovrebbe aggiungere anche il verbo PUT? –

0

La corretta gestione della richiesta OPZIONI di pre-volo è necessaria, ma NON SUFFICIENTE per il funzionamento delle richieste di risorse tra siti.

Dopo che la richiesta OPTIONS torna con intestazioni soddisfacenti, tutte le risposte a eventuali richieste successive allo stesso URL devono anche avere l'intestazione "Access-Control-Allow-Origin" necessaria, altrimenti il ​​browser le inghiottirà e non comparirà nemmeno nella finestra del debugger. https://stackoverflow.com/a/11951532/5649869

+0

All'inizio lasciare solo i metodi http richiesti nei metodi consentiti. Quindi prova a fare una richiesta grezza usando curl 'curl -H" Origine: http://127.0.0.1 "--verbose http: // 127.0.0.1/api/v1.0/user'. Devi vedere le intestazioni di Access-Control-Allowed- * in risposta. Infine, prova a specificare l'host (http://127.0.0.1 o smth. Else) in AllowedOrigin. –

+0

Ho provato 'allowedHeaders (" xsrf-token ").exposedHeaders ("xsrf-token") 'ma ancora non funziona. Penso di aver bisogno di qualcosa del genere - 'if (" OPTIONS ".equals (request.getMethod())) { \t \t \t response.setStatus (HttpServletResponse.SC_OK); \t \t} 'ma non so come aggiungere questa logica nel' registro CorsRegistry' – alexanoid

2

Se lo stesso problema con cui CORS funzionava con il blocco dei dati primaverili, questo era il codice del filtro che ho usato.

/** 
* Until url{https://jira.spring.io/browse/DATAREST-573} is fixed 
* 
* @return 
*/ 
@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("OPTIONS"); 
    config.addAllowedMethod("HEAD"); 
    config.addAllowedMethod("GET"); 
    config.addAllowedMethod("PUT"); 
    config.addAllowedMethod("POST"); 
    config.addAllowedMethod("DELETE"); 
    config.addAllowedMethod("PATCH"); 
    source.registerCorsConfiguration("/**", config); 
    return new CorsFilter(source); 
} 
1

Per quello che il suo valore, la seguente soluzione combinazione ha funzionato per me:

1.

@Configuration 
public class CorsConfiguration { 

//This can be used in combination with @CrossOrigin on the controller & method. 

    @Bean 
    public WebMvcConfigurer corsConfigurer() { 
     return new WebMvcConfigurerAdapter() { 
      @Override 
      public void addCorsMappings(CorsRegistry registry) { 
       registry.addMapping("/**") 
         .allowedMethods("HEAD","OPTIONS") 
         .allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept"); 
      } 
     }; 
    } 
} 

2. @CrossOrigin sulla classe RestController. Avere @CrossOrigin legge le annotazioni @RequestMapping e i metodi HTTP in esso. Il resto delle richieste viene rifiutato con errore CORS.

Ma se la sicurezza di primavera nel tuo progetto non ti soddisfa, ti verrà sfortuna la soluzione di cui sopra.

Sto usando la versione di avvio a molla 1.5.4.RELEASE.

Problemi correlati