Skip to main content
CORS

Peticiones Cross-domain con Javascript en servicios REST con JAX-RS (CORS)

En este artículo explicaremos como habilitar CORS en servicios REST hechos con JAX-RS, para resolver el problema de acceso a dominios cruzados con Javascript.

El problema

Si estamos desarrollando aplicaciones web modernas con Javascript (Ionic, Angular, etc.) es posible que nos hayamos encontrado con el siguiente error a la hora de realizar nuestras llamadas AJAX (XMLHttpRequest) a los servicios REST:

XMLHttpRequest cannot load http://miservicio.es/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mi.app' is therefore not allowed access.

Es un mecanismo de seguridad de los navegadores modernos, que impiden que se puedan realizar peticiones AJAX en una aplicación que se está ejecutando en un dominio y puerto a un servicio que está ejecutándose en otro dominio y/o puerto diferente. En concreto estamos violando la política del mismo origen (SOP).

La solución: CORS

Cross-origin resource sharing (CORS) es un mecanismo estándar definido por el W3C que permite que se hagan llamadas JavaScript con XMLHttpRequests a otro dominio diferente al que originó el código JavaScript. Tales solicitudes de “dominio cruzado” estarían prohibidas por los navegadores web, según la política de seguridad SOP.

Para habilitarlo tendremos que incluir una nueva cabecera HTTP en la respuesta: Access-Control-Allow-Origin . Si recuerdas el mensaje de error anterior, esto es exactamente lo que el navegador está tratando de decirte. Cuando un navegador recibe una respuesta de una fuente de origen cruzado, comprobará si hay cabeceras CORS. Si el origen especificado en el encabezado de respuesta coincide con el origen actual, permite el acceso de lectura a la respuesta. De lo contrario, obtendrá el mensaje de error.

Es más práctico que sólo permitir peticiones de mismo origen y es más seguro que simplemente permitir todas las solicitudes de origen cruzado.

Implementar CORS con Jersey (JAX-RS)

Si tenemos nuestros servicios REST implentados con Jersey, como explicamos en un articulo anterior, podemos aplicar CORS mediante un filtro. Este filtro modificará las peticiones y respuestas inclyendo las cabeceras definidas por 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 ResponseCorsFilter implements ContainerResponseFilter {

	@Override
	public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException {
		response.getHeaders().add("Access-Control-Allow-Origin", "*");
		response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, Authorization");
		response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
	}
}

En el ejemplo anterior, el filtro ResponseCorsFilter siempre agrega las siguientes cabeceras:

  • Access-Control-Allow-Origin: El “*” significa que la solicitud puede provenir de cualquier dominio. De esta manera hacemos que la API REST sea pública.
  • Access-Control-Allow-Methods: indica que se permiten los métodos GET, POST, DELETE, PUT para acceder al recurso.
  • Access-Control-Allow-Headers: indica que los encabezados Origin, Content-Type, Acept y Authorization se pueden utilizar al realizar la solicitud.

Los filtros en los servicios JAX-RS deben implementar la interfaz ContainerResponseFilter. Para registrar el filtro en nuestra aplicación ulizamos la anotación @Provider.

Espero que te haya sido útil el artículo. Si tienes cualquier duda o sugerencia, no dudes en escribirme.

Deja un comentario

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

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

CERRAR