Как я могу разработать API JavaScript, который позволяет безопасно создавать междоменные сценарии? - PullRequest
16 голосов
/ 31 октября 2010

Мне нравится, как расходуется API Google Maps с использованием скрипта include, но я волнуюсь:

Мой API-интерфейс является «полуприватным», то есть доступен через Интернет, но должен обеспечивать безопасную передачу данных и некоторую аутентификацию. Данные должны оставаться конфиденциальными по сети, и один потребитель не сможет получить доступ к данным другого.

Как я могу использовать SSL и некоторую аутентификацию для обеспечения безопасности данных, но при этом доступ к ним «горизонтально» с простой HTML-страницы без использования прокси-сервера на стороне сервера? Нужно ли управлять ключами? Как ключи будут отправлены на сервер без перехвата? Могу ли я использовать OpenId (или какую-либо другую стороннюю аутентификацию) для аутентификации пользователей API или мне нужно создать свой собственный механизм аутентификации? Я был по всему Google и не могу найти хорошего руководства по разработке и безопасному развертыванию моего API.

Сейчас я использую REST и AJAX для их использования, но междоменные вызовы невозможны. Любая помощь или указатель в правильном направлении будет принята с благодарностью.

Ответы [ 5 ]

10 голосов
/ 31 октября 2010

Я бы, вероятно, использовал динамически генерируемый тег сценария с URL-адресом SSL, который содержал ключ в строке запроса, который был зашифрован открытым ключом.Сервер будет использовать закрытый ключ для дешифрования параметра строки запроса и возврата сценария, который включает соответствующую информацию (или нет, если ключ недействителен).Или что-то вдоль этих линий.Но я признаю, что на самом деле мне не приходилось делать это на практике.

Я бы также искал предшествующий уровень техники, например сервис Amazon S3.

Итак:

  1. Пользователь предоставляет секрет
  2. Код на стороне клиента использует открытый ключ для шифрования секрета
  3. JavaScript добавляет тег script, который включает URL
  4. Серверные дескрипторызапрос сценария, расшифровывает секрет, проверяет его и отправляет обратно соответствующий ответ.

Вам может потребоваться два цикла, поскольку в противном случае запрос к серверу может быть повторно использован черезатака в середине.Это может быть:

  1. JavaScript добавляет тег script, который запрашивает уникальный ключ (возможно, с некоторой противоречивой информацией, такой как исходный IP-адрес и некоторый случайный дополнительный ключ)
  2. Сервер отвечаетс одноразовым ключом, привязанным к этому IP
  3. Пользователь предоставляет секрет
  4. Код на стороне клиента использует открытый ключ для шифрования секрета, в том числе уникальный ключ от # 1
  5. JavaScript добавляет тег script, который включает URL
  6. Сервер обрабатывает запрос сценария, расшифровывает секрет, проверяет его и отправляет обратно соответствующий ответ.
  7. Ответ вполне может быть зашифрован (до некоторой степени) с использованием случайного ключа, включенного в # 1

Ничего из того, что я фактически сделал. (Или я? BWAa-ха-ха-ха ...) FWIW.

0 голосов
/ 13 ноября 2010

Не совсем уверен, что именно вопрос, я так понимаю, вы пытаетесь сделать jsonp-подобный вызов [https://secure.com], чтобы обработать / отобразить данные на [http://regular.com]?

Могут ли два сервера общаться друг с другом? Как насчет такого:

  1. Пользователь входит в систему [https://secure.com]

  2. После аутентификации secure.com генерирует токен (позволяет называть его синтаксином) и передает его непосредственно на регулярный сервер (сервер-сервер), например, как session_id, произвольное сообщение и шифр otp (давайте назовем это syncipher).

  3. Broswer получает cookie session_id, а Secure.com перенаправляет браузер на http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla

  4. Regular.com просматривает otp-шифр, используя session_id в качестве ключа, и расшифровывает otpencryptedmessage «blabla».

  5. Если дешифрованное сообщение совпадает с исходным сообщением в синтокене, мы можем убедиться, что пользователь вошел в систему [Regular.com] и регулярно.com генерирует другой токен (позволяет называть его acktoken, lolz) и передает его непосредственно [ secure.com], состоящий из session_id, произвольного ack-сообщения и другого otp-шифра (назовем его ackcipher).

  6. Затем Regular.com отправляет браузеру cookie-файл, состоящий из otpencryptedackmessage (назовем этот cookie-файл «Verified_session»).

  7. Завершить загрузку страницы.

Оттуда вы можете делать jsonp-подобные звонки на

https://secure.com/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value)

, где secure.com/getscript.js будет принимать проверенный токен, искать ackcipher на основе исходного cookie session_id, отправленного [secure.com] в качестве ключа, и расшифровывать сообщение otpencrypedackmessage. Если дешифрованное сообщение совпадает с подтвержденным сообщением, отобразите файл сценария.

Это похоже на трехстороннее рукопожатие. Секрет в том, что серверы должны иметь возможность напрямую общаться друг с другом, чтобы конфиденциально передавать секретные ключи. Вам не нужно использовать один и тот же session_id для обоих серверов, я просто использовал это в качестве простого ориентира, чтобы найти способ доступа к шифрам syn / ack otp. Шифры должны быть полностью скрыты от общественности.

0 голосов
/ 11 ноября 2010
  1. (сторонняя) Страница использует OAUTH или что-то подобное для аутентификации пользователя и получения токена с вашего сервера.
  2. Страница загружает IFRAME с вашего сервера через SSL, передавая токен для аутентификации.
  3. IFRAME может безопасно общаться с вашим сервером через SSL
  4. Использовать easyXDM или что-то подобное для связи между IFRAME и сторонней страницей, используя некоторые ограниченные RPC-подобныеили API, похожий на сокет, который вы создаете.

Или, если вы действительно не доверяете третьей стороне - выполните аутентификацию внутри iframe (тогда не нужно указывать oauth, просто используйте простую HTML-форму) исообщайте обо всем, что должна знать внешняя страница о пользователе, с помощью easyXDM.

0 голосов
/ 08 ноября 2010

Проверьте проект Forge с открытым исходным кодом javascript. Он обеспечивает реализацию TLS javascript, которая позволяет защищать междоменные запросы xhr. Это может быть полезно для вас:

http://digitalbazaar.com/2010/07/20/javascript-tls-1/

http://digitalbazaar.com/2010/07/20/javascript-tls-2/

https://github.com/digitalbazaar/forge

Одно потенциальное решение:

  1. Настройте сервер Apache для запуска вашего сайта.
  2. Получите сертификат SSL для вашего сайта.
  3. Установите мод apache, который поставляется вместе с Forge, для настройки междоменной политики, позволяющей другим сайтам получать доступ к вашему.
  4. Реализация TLS Host Forge на вашем сайте вместе с сертификатом вашего сайта в формате PEM.
  5. Скажите другим сайтам, чтобы они включали JavaScript с вашего сайта и использовали его для безопасных звонков на ваш сайт, чтобы делать все, что вы хотите.
0 голосов
/ 07 ноября 2010

OAuth может помочь в этой ситуации, если пользователь войдет в стороннее приложение и позволит вашему приложению получить доступ к стороннему приложению от их имени, используя маркер запроса при выполнении запросов xhr.http://oauth.net/documentation/getting-started/

========

Причина использования прокси на стороне сервера сводится к политике одного источника, встроенной в веб-браузеры: http://en.wikipedia.org/wiki/Same_origin_policy

По сути, браузер разрешает отправлять запросы только по адресу, с которого поступает страница (например, facebook.com может отправлять запросы только на URI facebook.com).Прокси-серверная сторона решает эту проблему, отправляя запросы к серверам вне текущего источника.Серверные прокси также являются наилучшей практикой для выполнения подобных запросов.

...