origin - spring access control expose headers
Spring CORS No hay encabezado ''Access-Control-Allow-Origin'' está presente (9)
Tengo el siguiente problema después de portar web.xml a la configuración de Java
No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:63342'' is therefore not allowed access.
Basado en algunas referencias de Spring, se ha intentado el siguiente intento:
@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
@Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
"Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}
Los valores elegidos se tomaron de un filtro web.xml que funciona:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param> </filter> <filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
¿Alguna idea de por qué el enfoque de configuración Spring java no funciona como lo hizo el archivo web.xml?
Cambie CorsMapping de Registry.addMapping
registry.addMapping("/*")
a
addCorsMappings
registry.addMapping("/**")
en el método
addCorsMappings
.
Echa un vistazo a esta Documentation Spring CORS.
De la documentation -
Habilitar CORS para toda la aplicación es tan simple como:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Puede cambiar fácilmente cualquier propiedad, así como también aplicar esta configuración CORS a un patrón de ruta específico:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}
Método del controlador Configuración CORS
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
}
Para habilitar CORS para todo el controlador:
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Incluso puede usar configuraciones CORS tanto a nivel de controlador como a nivel de método; Spring combinará los atributos de ambas anotaciones para crear una configuración de CORS fusionada.
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Como señaló @Geoffrey, con seguridad de primavera, necesita un enfoque diferente como se describe aquí: Spring Boot Security CORS
Consejo útil: si está utilizando Spring Data Rest, necesita un enfoque diferente.
@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.getCorsRegistry().addMapping("/**")
.allowedOrigins("http://localhost:9000");
}
}
La respuesta de Omkar es bastante completa.
Pero alguna parte de la parte de configuración global ha cambiado.
De acuerdo con la referencia de Spring Boot 2.0.2.
A partir de la versión 4.2, Spring MVC es compatible con CORS. El uso de la configuración CORS del método del controlador con anotaciones @CrossOrigin en su aplicación Spring Boot no requiere ninguna configuración específica. La configuración global de CORS se puede definir registrando un bean WebMvcConfigurer con un método personalizado addCorsMappings (CorsRegistry), como se muestra en el siguiente ejemplo:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
Sin embargo, la mayoría responde en esta publicación usando
WebMvcConfigurerAdapter
El tipo WebMvcConfigurerAdapter está en desuso
Desde Spring 5 solo necesita implementar la interfaz WebMvcConfigurer:
public class MvcConfig implements WebMvcConfigurer {
Esto se debe a que Java 8 introdujo métodos predeterminados en las interfaces que cubren la funcionalidad de la clase WebMvcConfigurerAdapter
Por alguna razón, si todavía alguien no puede evitar CORS, escriba el encabezado al que el navegador desea acceder su solicitud.
Agregue este bean dentro de su archivo de configuración.
@Bean public WebSecurityConfigurerAdapter webSecurity() { return new WebSecurityConfigurerAdapter() { @Override protected void configure(HttpSecurity http) throws Exception { http.headers().addHeaderWriter( new StaticHeadersWriter("Access-Control-Allow-Origin", "*")); } }; }
De esta manera podemos decirle al navegador que estamos permitiendo el origen cruzado de todo origen. si desea restringir desde una ruta específica, cambie el "*" a {'' http: // localhost: 3000 '', ""}.
Referencia útil para comprender este comportamiento https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example
Si está utilizando Spring Security ver> = 4.2, puede utilizar el soporte nativo de Spring Security en lugar de incluir el de Apache:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
El ejemplo anterior se copió de una publicación de blog de Spring en la que también puede encontrar información sobre cómo configurar CORS en un controlador, métodos de controlador específicos, etc. Además, también hay ejemplos de configuración XML, así como la integración de Spring Boot.
Siguiendo la respuesta de Omar, creé un nuevo archivo de clase en mi proyecto API REST llamado
WebConfig.java
con esta configuración:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}
Esto permite que cualquier origen acceda a la API y la aplica a todos los controladores en el proyecto Spring.
También tuve mensajes como
No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:63342'' is therefore not allowed access.
No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:63342'' is therefore not allowed access.
Había configurado los cors correctamente, pero lo que faltaba en webflux en RouterFuncion era aceptar y contestar los encabezados APPLICATION_JSON como en este código:
@Bean
RouterFunction<ServerResponse> routes() {
return route(POST("/create")
.and(accept(APPLICATION_JSON))
.and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}
Tuvimos el mismo problema y lo resolvimos usando la configuración XML de Spring de la siguiente manera:
Agregue esto en su archivo xml de contexto
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>