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 elCorsFilter
con Spring Security proporcionando unCorsConfigurationSource
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