openjdk.ruOpenJDK на русском

JEP 183: HTTP Cross-Origin Resource Sharing

Совместное использование ресурсов разных источников (Cross-Origin Resource Sharing) в HTTP

ОтветственныйMichael McMahon
ТипFeature
ОбластьSE
СтатусClosed / Withdrawn
Компонентcore-libs / java.net
Обсуждениеnet dash dev at openjdk dot java dot net
ТрудоёмкостьS
ДлительностьS
Зависит отJEP 140: Limited doPrivileged
РецензентыAlan Bateman, Chris Hegarty, Jeffrey Nisewanger
ОдобренBrian Goetz
Создан2013/03/26 20:00
Обновлён2017/09/04 15:30
Задача8046173

Аннотация

Реализовать протокол Cross Origin Resource Sharing (CORS) консорциума W3C, чтобы привести HTTP-стек Java в соответствие с HTML5 и современными веб-браузерами.

Мотивация

Код Java, работающий под управлением менеджера безопасности, сейчас ограничен политикой одного источника (same origin policy): сетевые соединения можно устанавливать только с источником кода, если явно не выданы разрешения.

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

Описание

При обращении к ресурсу, заданному URL, протокол CORS добавляет несколько дополнительных заголовков, шагов обработки и, возможно, ещё один цикл запрос/ответ. CORS определяет некоторые HTTP-запросы как простые (simple). Простые запросы разрешены всегда, без предварительной авторизации со стороны сервера. Непростому запросу должен предшествовать специальный предварительный (pre-flight) запрос, в котором у сервера спрашивают, будет ли разрешён непростой запрос. Результаты авторизации кэшируются.

Для кода приложения протокол CORS в основном прозрачен. Может быть определён небольшой API, основная функция которого — включать CORS для отдельных соединений, но также может быть определено системное свойство, включающее его глобально для всех соединений, чтобы существующий код мог использовать CORS без изменений. API также охватывал бы случаи, когда нужно задать следующие флаги:

  • нужно ли использовать учётные данные (т. е. cookie или HTTP-аутентификацию) в этом запросе, который может быть обращён к другому источнику; и

  • нужно ли принудительно выполнять предварительный запрос, даже если результат (предварительного запроса) уже закэширован.

API может выглядеть так:

public class java.net.HttpURLConnection {
    :
    public void setCORSParameters(
        boolean enable,
        boolean omitCredentials,
        boolean forcePreflight
    ) { ... }
}

Пример кода:

URL url = new URL("http://www.server.com/cross-origin-request/");
 HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
 urlc.setCORSParameters(true, false, false);
 urlc.setRequestMethod("POST");
 urlc.setRequestProperty("Content-Type", "application/xml");
 urlc.setDoOutput(true);
 OutputStream os = urlc.getOutputStream();
 os.write(... request body ...);
 ...

Определение протокола CORS стабильно, но ещё не окончательно, поэтому эта возможность на первых порах может быть реализована не как публичный API в пакете java.net. В таком случае она будет реализована как API, специфичный для JDK, или как системное свойство, которые могли бы развиваться по мере необходимости вместе с протоколом.

Тестирование

Эта возможность вводит новый механизм протокола, который нужно протестировать либо на реальных сторонних HTTP-серверах, либо с помощью тестов, построенных на основе встроенного HTTP-сервера JDK.

С использованием HTTP-сервера JDK разработан простой фреймворк модульных тестов. Тест задаётся как набор, состоящий из вызова клиентского API, ожидаемых HTTP-запросов и ответов с точки зрения сервера и ответа API с точки зрения клиента. Работа над этой возможностью будет включать набор таких модульных тестов.

Риски и допущения

По состоянию на январь 2013 года определение протокола CORS имеет в W3C статус «Candidate (кандидат) Recommendation» (рекомендация-кандидат). Предполагалось, что к началу марта оно станет «Proposed Recommendation» (предлагаемой рекомендацией), но этого не произошло. Если определение протокола CORS изменится, эту возможность придётся соответствующим образом переработать.

Зависимости

Эта возможность зависит от JEP 140: Limited doPrivileged.

Влияние

  • Совместимость: новое поведение будет включаться через новый API или системное свойство.

  • Безопасность: потребуется тщательная проверка, поскольку эта возможность ослабляет модель сетевой безопасности в двух отношениях:

    1. Для некоторых (простых) HTTP-запросов к другим источникам, как их определяет CORS, явное сетевое разрешение не потребуется.

    2. Решение о разрешениях для остальных (непростых) запросов будет делегировано серверу, на котором размещён целевой ресурс.

  • TCK: один новый метод, добавленный в существующий класс HttpURLConnection, а также несколько небольших изменений в существующих классах java.security.