restful origin jax enable domain cross control allow spring cors resteasy

jax - Spring-Resteasy-Cabecera de Cors Double Access-Control-Allow-Origin en respuesta



java restful cross domain (4)

Configuré una aplicación web con Spring 3 y Resteasy; dado que mis recursos requieren autenticación, no estoy autorizado a utilizar * como Access-Control-Allow-Origin. Así que configuré

org.jboss.resteasy.plugins.interceptors.CorsFilter

con el dominio de origen correcto. Esto funciona con un cliente de escritorio (Paw para Mac OS y otros), pero no con el navegador (Chrome); el problema es que la respuesta contiene un doble valor para Access-Control-Allow-Origin, que es el que he configurado y ''*''.

CorsFilter no tiene la culpa porque, incluso si configuras más de un origen, siempre pone solo un valor para el encabezado, el que solicitó la solicitud.

Simplemente no tengo idea de quién está poniendo ese encabezado extra (y erróneo), ¿alguna idea sobre dónde podría buscar? Tenga en cuenta que el encabezado doble se produce en las solicitudes GET, pero no en las solicitudes de OPCIONES.


Finalmente descubrí que hay un MessageBodyWriterInterceptor patentado en el classpath que hace un encabezado add incorrecto; ahora depende de mí eliminar eso. Una cosa que aprendí es que si algo sucede solo cuando hay un cuerpo para escribir, un buen punto de partida es sin duda la tubería de renderizado


No estoy seguro de dónde proviene su doble encabezado, pero ¿intentó utilizar un filtro personalizado? p.ej :

@Component @Order(Ordered.HIGHEST_PRECEDENCE) public class SimpleCorsFilter implements Filter { public SimpleCorsFilter() { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Content-Type"); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } @Override public void init(FilterConfig filterConfig) { } @Override public void destroy() { } }


Intenté las siguientes acciones y funcionó como un encanto:

Primero, registre la clase de proveedor CorsFilter en su web.xml:

<context-param> <param-name>resteasy.providers</param-name> <param-value>org.jboss.resteasy.plugins.interceptors.CorsFilter</param-value> </context-param>

Al hacerlo, su servidor ya está habilitado para manejar las solicitudes CORS, sin embargo, debe agregar algunos orígenes permitidos para que funcione, por lo tanto, debe tener acceso a la instancia de CorsFilter, que fue creada por RestEasy y luego agregar todas las URL que desea otorgar acceso o agregar un * si desea otorgar acceso a alguno.

En este sentido, si está utilizando la integración de RestEasy Spring, necesitará obtener una instancia de la clase org.jboss.resteasy.spi.ResteasyProviderFactory al conectarla automáticamente a su código:

@Autowired private ResteasyProviderFactory processor;

luego use un método de configuración anotado con @PostConstruct para obtener la instancia de CorsFilter de ResteasyProviderFactory como el siguiente fragmento de código:

@PostConstruct public void setUp() { ContainerRequestFilter[] requestFilters = processor.getContainerRequestFilterRegistry().preMatch(); CorsFilter filter = (CorsFilter) Iterables.getLast(Iterables.filter(Arrays.asList(requestFilters), Predicates.instanceOf(CorsFilter.class))); filter.getAllowedOrigins().add("*"); }

PD: estoy usando este marco:

  • Spring Framework 3.2.18.RELEASE
  • RestEasy 3.0.12.Final

¡Espero que ayude!


Para aquellos que luchan como yo, que no usan el inicio de la aplicación, sino solo Spring + Reasteasy.

Solo agregue en web.xml:

<context-param> <param-name>resteasy.providers</param-name> <param-value>package.to.your.cors.CORSFilter</param-value> </context-param>

Y crea la clase CORSFilter de Java como

package package.to.your.cors; import java.io.IOException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.Provider; @Provider public class CORSFilter implements ContainerResponseFilter { @Override public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext cres) throws IOException { cres.getHeaders().add("Access-Control-Allow-Origin", "*"); cres.getHeaders().add("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); cres.getHeaders().add("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type"); cres.getHeaders().add("Access-Control-Max-Age", "4800"); } }

Funciona a las mil maravillas.

PD: inspirado por la respuesta de s_bighead, pero no pude comentar su respuesta para agregar mis detalles.