java - resource - spring boot cors origin
Spring Data Rest y Cors (4)
Estoy desarrollando una aplicación Spring Boot con una interfaz Rest y un dardo al frente.
XMLHttpRequest ejecuta una solicitud OPTIONS que se maneja de forma totalmente correcta. Después de esto, se emite la solicitud GET final ("/ productos") y falla:
No hay encabezado ''Access-Control-Allow-Origin'' presente en el recurso solicitado. Por lo tanto, el origen '' http: // localhost: 63343 '' no tiene acceso permitido.
Después de algunas depuraciones, he encontrado lo siguiente: AbstractHandlerMapping.corsConfiguration se completa para todas las subclases, excepto RepositoryRestHandlerMapping.
En RepositoryRestHandlerMapping no hay configuración / cors presente en el momento de la creación, por lo que no se reconocerá como ruta / recurso cors.
=> No hay encabezados CORS conectados
¿Podría ser el problema?
¿Cómo puedo configurarlo?
Clases de configuración:
@Configuration
public class RestConfiguration extends RepositoryRestMvcConfiguration {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowCredentials(false).allowedOrigins("*").allowedMethods("PUT", "POST", "GET", "OPTIONS", "DELETE").exposedHeaders("Authorization", "Content-Type");
}
...
}
Incluso intenté establecer los Cors por anotación:
@CrossOrigin( methods = RequestMethod.GET, allowCredentials = "false")
public interface ProductRepository extends CrudRepository<Product, String> {
}
Encabezados de solicitud sin procesar:
GET /products HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
authorization: Basic dXNlcjpwYXNzd29yZA==
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/43.0.2357.130 Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:63343/inventory-web/web/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Encabezados de respuesta sin procesar:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 30 Jul 2015 15:58:03 GMT
Versiones utilizadas: Spring Boot 1.3.0.M2 Spring 4.2.0.RC2
¿Qué extraño?
De hecho, antes de Spring Data REST 2.6 (Ingalls) solo
HandlerMapping
instancias
HandlerMapping
creadas por Spring MVC
WebMvcConfigurationSupport
y los controladores anotados con
@CrossOrigin
eran conscientes de CORS.
Pero ahora que
DATAREST-573
se ha solucionado,
RepositoryRestConfiguration
ahora expone un
getCorsRegistry()
para la configuración global y
@CrossOrigin
anotaciones
@CrossOrigin
en los repositorios también se reconocen, por lo que este es el enfoque recomendado.
Consulte la respuesta
https://.com/a/42403956/1092077
para ver ejemplos concretos.
Para las personas que tienen que apegarse a Spring Data REST 2.5 (Hopper) o versiones anteriores, creo que la mejor solución es usar un enfoque basado en filtros.
Obviamente, podría usar Tomcat, Jetty o
este
, pero tenga en cuenta que Spring Framework 4.2 también proporciona un
CorsFilter
que usa la misma lógica de procesamiento CORS que los
@CrossOrigin
y
addCorsMappings(CorsRegistry registry)
.
Al pasar una instancia de
CorsFilter
parámetro del constructor
CorsFilter
, puede obtener fácilmente algo tan poderoso como el soporte global nativo de Spring CORS.
Si está utilizando Spring Boot (que admite beans de
Filter
), podría ser algo como:
@Configuration
public class RestConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Desde que se realizó el tren de Ingalls , el soporte de CORS en Spring Data ahora está en marcha . Hay dos formas de lidiar con:
-
La anotación
@CrossOrigin
con la especificación deorigins
,methods
yallowedHeaders
través de una interfaz@RepositoryRestResource
.@CrossOrigin(...) @RepositoryRestResource public interface PageRepository extends CrudRepository<Page, Long> { ... }
-
Una configuración global con
RepositoryRestConfiguration
dentro de una clase@Configuration
.@CrossOrigin
es necesario marcar repositorios por@CrossOrigin
.@Configuration public class GlobalRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.getCorsRegistry() .addMapping(CORS_BASE_PATTERN) .allowedOrigins(ALLOWED_ORIGINS) .allowedHeaders(ALLOWED_HEADERS) .allowedMethods(ALLOWED_METHODS); } }
Estaba tratando de llegar al servicio de descanso de primavera desde angular. El proyecto Spring Rest implementado en el servidor Tomcat y angular es el servidor angular predeterminado. Me enfrenté a este problema cuando está pasando de angular a servicio. Traté de seguir
https://juristr.com/blog/2016/11/configure-proxy-api-angular-cli/
Pero el problema sigue ahí. Gracias a mi senior ''Abbas bhai'', sugirió agregar alguna configuración en el archivo de configuración de primavera para evitar este problema, así que agregué este código en la configuración de primavera.
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@ComponentScan("org.liferayasif.backend")
public class RestConfig extends WebMvcConfigurerAdapter{
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
/*
* (non-Javadoc)
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
* To avoid ''Access-Control-Allow-Origin''
* Above error arising when I am hitting from angular to our rest service
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Este método resolvió mis cors ''Access-Control-Allow-Origin''.
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
Como referencia puedo descargar todo mi proyecto
Mi enlace url github:
https://github.com/asifaftab87/SpringPersistenceHibernate
Sucursal - seguridad
Proyecto - Modelo
Por alguna razón, el enfoque sugerido en la respuesta aceptada anterior no funcionó para mí después de actualizar Spring Boot 1.5.2 a 1.5.6.
Como también señaló el comentario de @ BigDong, la excepción que obtuve fue:
BeanInstantiationException: no se pudo crear una instancia [javax.servlet.Filter]: el método de fábrica ''springSecurityFilterChain'' produjo una excepción; la excepción anidada es org.springframework.beans.factory.BeanNotOfRequiredTypeException: se espera que el bean llamado ''corsFilter'' sea del tipo ''org.springframework.web.filter.CorsFilter'' pero en realidad era del tipo ''org.springframework.boot.web .servlet.FilterRegistrationBean
Entonces, esto es lo que se me ocurrió para obtener una configuración CORS "global" para todos los puntos finales en nuestra API REST, ya sea que se implementen utilizando Spring Data Rest o Spring MVC, con todos los puntos finales protegidos por Spring Security.
No pude conectar un
CorsFilter
a la tubería de solicitud en el punto correcto, por lo que configuré SDR y MVC por separado, sin embargo,
CorsRegistry
la misma configuración para su
CorsRegistry
través de este asistente:
public static void applyFullCorsAllowedPolicy(CorsRegistry registry) {
registry.addMapping("/**") //
.allowedOrigins("*") //
.allowedMethods("OPTIONS", "HEAD", "GET", "PUT", "POST", "DELETE", "PATCH") //
.allowedHeaders("*") //
.exposedHeaders("WWW-Authenticate") //
.allowCredentials(true)
.maxAge(TimeUnit.DAYS.toSeconds(1));
}
Y luego para MVC:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// enables CORS as per
// https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html#cors
http.cors()
.and() // ...
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
applyFullCorsAllowedPolicy(registry);
}
};
}
}
Y luego para SDR:
public class CustomRepositoryRestMvcConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setReturnBodyOnCreate(true);
config.setReturnBodyForPutAndPost(true);
config.setReturnBodyOnUpdate(true);
config.setMaxPageSize(250);
config.setDefaultPageSize(50);
config.setDefaultMediaType(MediaTypes.HAL_JSON);
config.useHalAsDefaultJsonMediaType(true);
CustomWebSecurityConfiguration.applyFullCorsAllowedPolicy(config.getCorsRegistry());
}
Aquí hay alguna referencia adicional sobre el tema que me ayudó a llegar a esta respuesta: