Saltar al contenido

Problema de CORS: no hay un encabezado ‘Access-Control-Allow-Origin’ en el recurso solicitado

Luego de observar en varios repositorios y foros de internet al concluir nos hemos encontrado la solución que te compartiremos a continuación.

Solución:

La solicitud de verificación previa de CORS usa HTTP OPTIONS sin credenciales, consulte Intercambio de recursos de origen cruzado:

De lo contrario, haz un solicitud de verificación previa. Obtenga la URL de la solicitud desde la fuente de origen utilizando la fuente de referencia como fuente de referencia de anulación con el indicador de redirección manual y el indicador de bloqueo de cookies establecidos, utilizando el método OPCIONES y con las siguientes restricciones adicionales:

  • Incluya un encabezado Access-Control-Request-Method con como valor de campo de encabezado el método de solicitud (incluso cuando se trata de un método simple).
  • Si los encabezados de solicitud de autor no están vacíos, incluya un encabezado Access-Control-Request-Headers con como valor de campo de encabezado una lista separada por comas de los nombres de campo de encabezado de los encabezados de solicitud de autor en orden lexicográfico, cada uno convertido a minúsculas ASCII (incluso cuando uno o más son un encabezado simple).
  • Excluye los encabezados de solicitud de autor.
  • Excluir credenciales de usuario.
  • Excluye el cuerpo de la entidad de solicitud.

Tienes que permitir el acceso anónimo para HTTP OPTIONS.

Su código modificado (y simplificado):

@Override
protected void configure(HttpSecurity http) throws Exception 
   http
       .authorizeRequests()
           .andMatchers(HttpMethod.OPTIONS, "/**").permitAll()
           .antMatchers("/login").permitAll()
           .anyRequest().fullyAuthenticated()
           .and()
       .httpBasic()
           .and()
       .sessionManagement()
           .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           .and()
       .csrf().disable();

Desde Spring Security 4.2.0, puede usar el soporte incorporado, consulte la referencia de Spring Security:

19. CORAZON

Spring Framework proporciona soporte de primera clase para CORS. CORS debe procesarse antes de Spring Security porque la solicitud previa al vuelo no contendrá ninguna cookie (es decir, la JSESSIONID). Si la solicitud no contiene ninguna cookie y Spring Security es el primero, la solicitud determinará que el usuario no está autenticado (ya que no hay cookies en la solicitud) y la rechazará.

La forma más fácil de asegurarse de que CORS se maneje primero es usar el CorsFilter. Los usuarios pueden integrar el CorsFilter con Spring Security proporcionando un CorsConfigurationSource usando lo siguiente:

@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;
  

Desde Spring Security 4.1, esta es la forma correcta de hacer que Spring Security admita CORS (también necesario en Spring Boot 1.4/1.5):

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    

y:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
//        http.csrf().disable();
        http.cors();
    

    @Bean
    public CorsConfigurationSource corsConfigurationSource() 
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

Hacer no haga cualquiera de los siguientes, que son la forma incorrecta de intentar resolver el problema:

  • http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
  • web.ignoring().antMatchers(HttpMethod.OPTIONS);

Referencia: http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *