CORS в JAX-RS

CORS в JAX-RS

1. обзор

В этой быстрой статье мы узнаем, как включитьCORS (Cross-Origin Resource Sharing) в системе на основеJAX-RS. Мы создадим приложение поверхJAX-RS, чтобы включить механизмCORS.

2. Как включить механизм CORS

Есть два способа включить CORS в JAX-RS. Первый и самый базовый способ - создать фильтр для вставки необходимого заголовка ответа во время выполнения каждого запроса. Другой - вручную добавить соответствующий заголовок в каждую конечную точку URL.

В идеале следует использовать первый раствор; однако, если это не вариант, вариант с ручным управлением тоже вполне подойдет.

2.1. Использование фильтра

JAX-RS имеет интерфейсContainerResponseFilter, реализованный фильтрами ответа контейнера. Как правило, этот экземпляр фильтра применяется глобально к любому HTTP-ответу.

Мы реализуем этот интерфейс для создания настраиваемого фильтра, который будет вставлять заголовокAccess-Control-Allow-* в каждый исходящий запрос и включать механизмCORS:

@Provider
public class CorsFilter implements ContainerResponseFilter {

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

Пара моментов здесь:

  • Фильтры, реализующиеContainerResponseFilter, должны быть явно аннотированы@Provider, чтобы их обнаружила среда выполнения JAX-RS.

  • Мы добавляем заголовок «Access-Control-Allow-» с «», это означает, что к любым конечным точкам URL этого экземпляра сервера можно получить доступ через любой домен; если мы хотим явно ограничить междоменный доступ, мы должны упомянуть этот домен в этом заголовке

2.2. Использование модификации заголовка в каждой конечной точке

Как было сказано ранее, мы также можем явно внедрить заголовок «Access-Control-Allow-*» на уровне конечной точки:

@GET
@Path("/")
@Produces({MediaType.TEXT_PLAIN})
public Response index() {
    return Response
      .status(200)
      .header("Access-Control-Allow-Origin", "*")
      .header("Access-Control-Allow-Credentials", "true")
      .header("Access-Control-Allow-Headers",
        "origin, content-type, accept, authorization")
      .header("Access-Control-Allow-Methods",
        "GET, POST, PUT, DELETE, OPTIONS, HEAD")
      .entity("")
      .build();
}

Здесь следует отметить следующее: если мы пытаемся включитьCORS в большом приложении, мы не должны пробовать этот метод, потому что в этом случае мы должны вручную вводить заголовок в каждую конечную точку URL, что приведет к дополнительным накладные расходы.

Однако этот метод можно использовать в приложениях, где нам нужно включитьCORS только в некоторых конечных точках URL.

3. тестирование

Как только приложение будет запущено, мы можем проверить заголовки, используя команды curl. Пример вывода заголовков должен выглядеть примерно так:

HTTP/1.1 200 OK
Date : Tue, 13 May 2014 12:30:00 GMT
Connection : keep-alive
Access-Control-Allow-Origin : *
Access-Control-Allow-Credentials : true
Access-Control-Allow-Headers : origin, content-type, accept, authorization
Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD
Transfer-Encoding : chunked

Более того, мы можем создать простую функцию AJAX и проверить междоменную функциональность:

function call(url, type, data) {
    var request = $.ajax({
      url: url,
      method: "GET",
      data: (data) ? JSON.stringify(data) : "",
      dataType: type
    });

    request.done(function(resp) {
      console.log(resp);
    });

    request.fail(function(jqXHR, textStatus) {
      console.log("Request failed: " + textStatus);
    });
};

Конечно, для того, чтобы действительно выполнить проверку, нам нужно будет запустить ее в другом источнике, нежели API, который мы используем.

Вы можете легко сделать это локально, запустив клиентское приложение на отдельном порту -since the port does determine the origin.

4. Заключение

В этой статье мы показали, как реализовать механизмCORS в приложениях на основе JAX-RS.

Как всегда, доступен полный исходный кодover on GitHub.