Я пытаюсь найти свой путь вокруг спецификации OAuth, ее требований и любых реализаций, которые я могу найти, и до сих пор это действительно похоже на больше проблем, чем на их ценность, потому что мне трудно найти единственный ресурс, который тянет все это вместе. Или, может быть, это просто то, что я ищу что-то более специализированное, чем большинство учебников.
У меня есть набор существующих API-интерфейсов - некоторые из них на Java, некоторые из них - на PHP, которые мне теперь нужно защитить, и по ряду причин OAuth кажется правильным путем. К сожалению, моя неспособность отследить правильные ресурсы, чтобы помочь мне получить провайдера и запустить, бросает вызов этой теории. Поскольку в большинстве случаев это будет использование API системы для системы, мне нужно будет реализовать двухстороннего поставщика. Имея это в виду...
Спасибо за вашу помощь.
Ответ 2
Роб, не уверенный, где вы приземлились на это, но хотел добавить мои 2 цента на тот случай, если кто-то другой столкнулся с этим вопросом.
Я более или менее задавал один и тот же вопрос несколько месяцев назад и слышал о "OAuth" в течение большей части года. Я разрабатывал API REST, который мне нужно было защитить, поэтому я начал читать об OAuth... и тогда мои глаза начали катиться назад в моей голове.
Я, вероятно, дал хороший день или 2 чтения и чтения, пока я не решил, как и вы, что OAuth запутывал мусор и просто отказался от него.
Итак, я начал изучать способы защиты API в целом и начал лучше разбираться в способах этого. Наиболее популярным способом, по-видимому, является отправка запросов API вместе с контрольной суммой всего сообщения (закодированного секретом, которое только вы и сервер знаете), что сервер может использовать, чтобы решить, было ли это сообщение изменено на нем от клиента, например:
- Клиент отправляет /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
- Сервер получает все это, ищет пользователя "123" в базе данных, загружает свой секретный ключ и затем (используя тот же самый метод, который использует клиент), повторно вычисляет его СОБСТВЕННУЮ контрольную сумму с учетом аргументов запроса.
- Если серверная контрольная сумма и клиентская контрольная сумма совпадают, запрос в порядке и выполняется, если нет, то он считается измененным и отклоненным.
Контрольная сумма называется HMAC, и если вам нужен хороший пример этого, это то, что используют веб-службы Amazon (они называют аргумент "сигнатура", а не "контрольная сумма" ).
Поэтому, учитывая, что одним из ключевых компонентов этой работы является то, что клиент и сервер должны генерировать HMAC таким же образом (иначе они не совпадают), должны быть правила о том, КАК объединить все аргументы... тогда я вдруг понял все, что "естественный порядок байтов параметров" держится от OAuth... он просто определял правила создания сигнатуры, потому что это необходимо.
Другим моментом является то, что каждый параметр, который вы включаете в генерацию HMAC, является значением, которое затем не может быть изменено при отправке запроса.
Итак, если вы просто кодируете стержень URI в качестве подписи, например:
- /user.json == askJdla9/kjdas + Askj2l8add
тогда единственное, что в вашем сообщении, которое нельзя подделать, это URI, все аргументы могут быть подделаны, потому что они не являются частью значения "контрольной суммы", которое сервер будет пересчитывать.
В качестве альтернативы, даже если вы включаете КАЖДЫЙ параметр в вычисление, вы по-прежнему рискуете "атаками повтора", когда злонамеренный средний человек или evesdropped может перехватить вызов API и просто повторно пересылать его на сервер снова и снова.
Вы можете исправить это, добавив временную метку (всегда использовать UTC) в вычислении HMAC.
НАПОМИНАНИЕ: Поскольку серверу необходимо вычислить тот же HMAC, вы должны отправить любое значение, которое вы используете в расчете. ЗА ИСКЛЮЧЕНИЕМ ВАШЕГО СЕКРЕТНОГО КЛЮЧА (OAuth называет это user_secret, я думаю). Поэтому, если вы добавляете метку времени, убедитесь, что вы отправили параметр timestamp вместе с вашим запросом.
Если вы хотите сделать API защищенным от повторных атак, вы можете использовать значение nonce (это одноразовое использование, которое генерирует сервер, дает клиенту, клиент использует его в HMAC, отправляет обратно запрос, сервер подтверждает и затем отмечает это значение nonce как "использованное" в БД и никогда не позволяет другому запросу использовать его снова).
ПРИМЕЧАНИЕ: "nonce" - это действительно точный способ решения проблемы "повторной атаки". Временные метки велики, но поскольку компьютеры не всегда имеют значения временной метки синхронизации, вы должны разрешить приемлемое окно на на стороне сервера, как "старый" запрос может быть (скажем, 10 минут, 30 минут, 1 час.... Amazon использует 15 минут), прежде чем мы примем или отклоним его. В этом случае ваш API технически уязвим в течение всего времени.
Я думаю, что значения nonce велики, но их нужно использовать только в API, которые имеют решающее значение для их целостности. В моем API мне это не нужно, но было бы тривиально добавить позже, если бы пользователи потребовали его... Мне просто нужно было бы добавить таблицу "nonce" в моей БД, выставить новый API для таких клиентов, как:
а затем, когда они отправят это мне обратно в вычислении HMAC, мне нужно будет проверить БД, чтобы убедиться, что он никогда не использовался до и после использования, помечайте его как таковой в БД, поэтому, если запрос EVER пришел снова с тем же самым nonce я бы отказался от него.
Резюме
Во всяком случае, чтобы сделать длинную историю коротким, все, что я только что описал, в основном то, что известно как "2-legged OAuth". Не существует дополнительного шага к полномочиям (Twitter, Facebook, Google и т.д.) Для авторизации клиента, этот шаг удаляется, и вместо этого сервер неявно доверяет клиенту, если HMAC, с которым они отправляют, совпадают. Это означает, что клиент имеет право secret_key и подписывает его с ним, поэтому сервер доверяет ему.
Если вы начинаете смотреть в Интернете, это, по-видимому, является предпочтительным методом защиты API-методов сейчас - adays или что-то в этом роде. Amazon почти точно использует этот метод, за исключением того, что использует несколько другой комбинированный метод для своих параметров, прежде чем подписывать все это на создание HMAC.
Если вам интересно, я написал все это путешествие и думал, как я его изучал. Это может помочь организовать экскурсию по руководству этим процессом.