Предыстория: я написал клиентские и серверные стеки для OAuth 1.0a и 2.0.
И OAuth 1.0a, и 2.0 поддерживают двухстороннюю аутентификацию , при которой сервер уверен в идентичности пользователя, и трехстороннюю аутентификацию. , где сервер гарантируется поставщиком контента для идентификации пользователя. Трехсторонняя аутентификация - то, где запросы авторизации и токены доступа вступают в игру, и важно отметить, что OAuth 1 также имеет их.
Сложный: трехсторонняя аутентификация
Основной смысл спецификаций OAuth заключается в том, чтобы поставщик контента (например, Facebook, Twitter и т. Д.) Гарантировал серверу (например, веб-приложению, которое хочет общаться с поставщиком контента от имени клиента), что клиент имеет некоторую идентичность , То, что предлагает трехсторонняя аутентификация, - это возможность сделать это без необходимости когда клиенту или серверу знать детали этой личности (например, имя пользователя и пароль).
Не вдаваясь (?) В детали OAuth:
- Клиент отправляет запрос авторизации на сервер, который подтверждает, что клиент является законным клиентом своего сервиса.
- Сервер перенаправляет клиента к поставщику контента для запроса доступа к его ресурсам.
- Поставщик контента проверяет личность пользователя и часто запрашивает у него разрешение на доступ к ресурсам.
- Поставщик контента перенаправляет клиента обратно на сервер, уведомляя его об успехе или сбое. Этот запрос включает в себя код авторизации в случае успеха.
- Сервер отправляет внеполосный запрос поставщику контента и обменивает код авторизации на токен доступа.
Теперь сервер может отправлять запросы поставщику контента от имени пользователя, передавая маркер доступа.
Каждый обмен (клиент-> сервер, сервер-> контент-провайдер) включает в себя проверку общего секрета, но, поскольку OAuth 1 может работать по незашифрованному соединению, каждая проверка не может передавать секрет по проводам.
Это сделано, как вы заметили, с HMAC. Клиент использует секрет, которым он делится с сервером, чтобы подписать аргументы для своего запроса авторизации. Сервер принимает аргументы, сам подписывает их ключом клиента и может видеть, является ли он законным клиентом (на шаге 1 выше).
Эта подпись требует, чтобы и клиент, и сервер согласовали порядок аргументов (поэтому они подписывают одну и ту же строку), и одна из основных претензий к OAuth 1 заключается в том, что для сортировки и сервера требуются как сервер, так и клиенты. подписывать одинаково. Это сложный код, и он либо прав, либо вы получаете 401 Unauthorized
с небольшой помощью. Это увеличивает барьер для написания клиента.
Требуя, чтобы запрос авторизации выполнялся по SSL, OAuth 2.0 устраняет необходимость сортировки аргументов и подписи в целом. Клиент передает свой секрет на сервер, который проверяет его напрямую.
Те же самые требования присутствуют в соединении сервер-> контент-провайдер, и поскольку это SSL, который устраняет один барьер для записи сервера, который обращается к сервисам OAuth.
Это значительно упрощает шаги 1, 2 и 5 выше.
Таким образом, на данный момент наш сервер имеет токен постоянного доступа, который является эквивалентом имени пользователя / пароля для пользователя. Он может отправлять запросы поставщику контента от имени пользователя, передавая этот маркер доступа как часть запроса (в качестве аргумента запроса, заголовка HTTP или данных формы POST).
Если доступ к контентной службе осуществляется только через SSL, то все готово. Если он доступен через обычный HTTP, мы бы хотели каким-то образом защитить этот маркер постоянного доступа. Любой, кто прослушивает соединение, сможет получить доступ к контенту пользователя навсегда.
Способ, который решается в OAuth 2, заключается в использовании токена обновления . Токен обновления становится эквивалентом постоянного пароля и передается только по SSL . Когда серверу требуется доступ к контентной службе, он обменивает токен обновления на токен недолгого доступа. Таким образом, все сниффы HTTP-доступа осуществляются с токеном, срок действия которого истекает. Google использует 5-минутный срок действия своих API OAuth 2.
Таким образом, кроме токенов обновления, OAuth 2 упрощает все коммуникации между клиентом, сервером и поставщиком контента. А токены обновления существуют только для обеспечения безопасности при доступе к контенту в незашифрованном виде.
Двуногая аутентификация
Однако иногда серверу просто необходимо контролировать доступ к своему собственному контенту. Двусторонняя аутентификация позволяет клиенту аутентифицировать пользователя непосредственно на сервере.
OAuth 2 стандартизирует некоторые расширения OAuth 1, которые широко использовались. Тот, который я знаю лучше всего, был представлен Twitter как xAuth . Это можно увидеть в OAuth 2 в качестве учетных данных владельца ресурса .
По сути, если вы можете доверять клиенту учетные данные пользователя (имя пользователя и пароль), они могут обмениваться ими напрямую с поставщиком контента для получения токена доступа. Это делает OAuth намного более полезным в мобильных приложениях - при трехсторонней аутентификации вам необходимо встроить HTTP-представление для обработки процесса авторизации с помощью контент-сервера.
С OAuth 1 это не было частью официального стандарта и требовало такой же процедуры подписания, как и все другие запросы.
Я только что реализовал серверную часть OAuth 2 с помощью учетных данных владельца ресурса, и с точки зрения клиента получение токена доступа стало простым: запрос маркера доступа с сервера, передача идентификатора / секрета клиента в качестве заголовка авторизации HTTP и логин / пароль пользователя как данные формы.
Преимущество: простота
Таким образом, с точки зрения разработчика, основные преимущества, которые я вижу в OAuth 2, заключаются в уменьшении сложности. Это не требует процедуры подписания запроса, что не совсем сложно, но, безусловно, сложно. Это значительно сокращает объем работы, необходимой для работы в качестве клиента службы, и именно там (в современном мобильном мире) вы больше всего хотите минимизировать боль. Снижение сложности на стороне сервера-> контент-провайдера делает его более масштабируемым в центре обработки данных.
И это кодифицирует в стандарт некоторые расширения OAuth 1.0a (например, xAuth), которые сейчас широко используются.