Подробное объяснение авторизации и аутентификации OAuth 2.0

Безопасность
Подробное объяснение авторизации и аутентификации OAuth 2.0

1. Понимание OAuth 2.0

1.1 Сценарии применения OAuth 2.0

Стандарт OAuth 2.0 в настоящее время широко используется в сторонних сценариях входа в систему.Ниже приведены виртуальные роли, объясняющие, что OAuth2 может сделать для нас.Цитируя статью Руан ИфэнПонимание OAuth 2.0Пример в:

Существует веб-сайт «облачной печати», который может распечатывать фотографии пользователей, хранящиеся в Google. Чтобы использовать эту услугу, пользователи должны разрешить «облачной печати» читать свои фотографии, хранящиеся в Google.

Проблема в том, что Google разрешает «облачной печати» читать эти фотографии только с разрешения пользователя. Тогда как «Облачная печать» получает авторизацию пользователей?

Традиционный метод заключается в том, что пользователи сообщают «облачной печати» свое имя пользователя и пароль Google, и последний может прочитать фотографию пользователя. Этот подход имеет следующие серьезные недостатки.

(1) «Облачная печать» сохранит пароль пользователя для последующих служб, что очень небезопасно. (2) Google пришлось развернуть вход с паролем, а мы знаем, что простой вход с паролем небезопасен. (3) «Виртуальная печать» имеет право на получение всех данных, хранящихся у пользователя в Google, и пользователь не может ограничивать объем и срок действия разрешения, полученного «Виртуальной печатью». (4) Только изменив пароль, пользователь может отозвать право на «Облачную печать». Однако это приведет к аннулированию всех других сторонних приложений, авторизованных пользователем. (5) Взлом одного стороннего приложения приведет к утечке паролей пользователей, а также к утечке всех защищенных паролем данных.

1.2 Концепция существительного

OAuth был создан для решения этих проблем. Прежде чем подробно объяснять OAuth, необходимо прояснить некоторые основные понятия, а следующие понятия абстрагируются от приведенных выше сценариев.

сторонние приложения

Third-party application: стороннее приложение, также известное в этой статье как «клиент», то есть «облачная печать» в примере из предыдущего раздела.

Поставщик услуг HTTP

HTTP service: поставщик услуг HTTP, именуемый в этой статье «поставщиком услуг», то есть Google в примере из предыдущего раздела.

владелец ресурса

Resource Owner: владелец ресурса, также известный как «пользователь» в этой статье.

пользовательский агент

User Agent: Агент пользователя, в данном случае браузер.

Сервер аутентификации

Authorization server: Сервер аутентификации, то есть сервер, который поставщик услуг использует исключительно для обработки аутентификации.

сервер ресурсов

Resource server: Сервер ресурсов, то есть сервер, на котором поставщик услуг хранит созданные пользователями ресурсы. Он и сервер аутентификации могут быть одним сервером или другим сервером.

Зная приведенные выше термины, нетрудно понять, что роль OAuth заключается в том, чтобы позволить «клиенту» получить авторизацию «пользователя» безопасным и контролируемым образом, чтобы взаимодействовать с «поставщиком услуг».

Во-вторых, процесс авторизации и аутентификации OAuth.

2.1 Идеи аутентификации

Между «клиентом» и «поставщиком услуг» OAuth устанавливаетуровень авторизации(уровень авторизации). «Клиент» не может напрямую войти в «поставщика услуг», только уровень авторизации, который отличает пользователя от клиента. Токен, используемый «клиентом» для входа на уровень авторизации, отличается от пароля пользователя. Пользователь может указать область разрешений и срок действия токена уровня авторизации при входе в систему.

После того, как «клиент» входит в систему на уровне авторизации, «поставщик услуг» открывает данные, сохраненные пользователем, «клиенту» в соответствии с областью разрешений и сроком действия токена.

2.2 Процесс сертификации

Блок-схема OAuth 2.0 в официальном документе RFC 6749 немного неясна и оптимизирована:

  1. После того, как пользователь получает доступ к стороннему приложению (называемому клиентом), клиент требует от пользователя предоставить авторизацию.
  2. Пользователь соглашается авторизовать клиента.
  3. Клиент использует авторизацию, полученную на шаге 2, для запроса токена с сервера аутентификации.
  4. После того, как сервер аутентификации аутентифицирует клиента, он подтверждает его правильность и соглашается выдать токен.
  5. Клиент использует токен для обращения к серверу ресурсов для получения ресурса.
  6. Сервер ресурсов подтверждает правильность маркера и соглашается открыть ресурс клиенту.

Вторым шагом в вышеизложенном является ключ, то есть то, как пользователь может авторизовать клиента. С этой авторизацией клиент может получить токен, а затем использовать токен для получения ресурсов.

Три, четыре режима авторизации

Из предыдущего раздела можно сделать вывод, что действие авторизации пользователя для клиента является ядром, и клиент должен получить авторизацию пользователя (предоставление авторизации), чтобы получить токен (токен доступа). OAuth 2.0 определяет четыре метода авторизации:

3.1 Режим кода авторизации

Метод кода авторизации означает, что стороннее приложение сначала запрашивает код авторизации, а затем использует этот код для получения токена.

3.2 Упрощенный режим (IMPLICIT)

Некоторые веб-приложения представляют собой чистые интерфейсные приложения без серверной части. В настоящее время вышеуказанный метод использовать нельзя, и токен должен храниться во внешнем интерфейсе. В RFC 6749 указан второй способ, позволяющий выдавать токены непосредственно во внешний интерфейс. Этот метод не имеет промежуточного шага кода авторизации, поэтому он называется (код авторизации) «неявным».

3.3 Режим пароля (учетные данные пароля владельца ресурса)

Если у вас высокий уровень доверия к приложению, RFC 6749 также позволяет пользователям напрямую сообщать приложению свое имя пользователя и пароль. Приложение использует ваш пароль для запроса токена, который называется «пароль».

3.4 Режим клиента (учетные данные клиента)

Последний метод — учетные данные клиента, который подходит для приложений командной строки без внешнего интерфейса, то есть с запросом токена в командной строке.

4. Подробное объяснение режима кода авторизации

4.1 Процесс режима кода авторизации

Режим кода авторизации (код авторизации) — это режим авторизации с наиболее полными функциями и наиболее строгим и безопасным процессом. Его особенность в том, что через клиентвнутренний сервер, для взаимодействия с сервером аутентификации «Поставщика услуг».

Обратите внимание, что этот метод подходит для тех веб-приложений, у которых есть бэкенд. Код авторизации передается через переднюю часть, токен хранится в задней части, а вся связь с сервером ресурсов осуществляется в задней части. Такое разделение интерфейса и сервера позволяет избежать утечки токенов.

Процесс режима кода авторизации выглядит следующим образом:

  1. Пользователь обращается к клиенту, и клиент направляет пользователя на сервер аутентификации.
  2. Пользователь выбирает, авторизовать ли клиента.
  3. Предполагая, что пользователь предоставляет авторизацию, сервер аутентификации направляет пользователя на предварительно указанный клиентом «URI перенаправления» (URI перенаправления) вместе с кодом авторизации.
  4. Клиент получает код авторизации, прикрепляет более ранний «URI перенаправления» и запрашивает токен с сервера аутентификации. Этот шаг на стороне клиентавнутренний серверсделано выше, невидимым для пользователя.
  5. Сервер аутентификации проверяет код авторизации и URI перенаправления и после подтверждения правильности отправляет токен доступа и токен обновления клиенту.

Как видно из вышеприведенного описания процесса, только второй шаг требует от пользователя выполнения операции авторизации, а последующие процессы представляют собой «тихие» операции в фоне клиента и фоне сервера аутентификации, что незаметно для Пользователь.

Ниже приведены параметры, необходимые для вышеуказанных шагов.

4.2 Пять шагов процесса режима кода авторизации

Шаг 1

Параметр Описание

На шаге 1 URI, который клиент должен применить для проверки подлинности, содержит следующие параметры:

  • response_type: указывает тип авторизации,обязательный, значение здесь фиксируется как "код"
  • client_id: указывает идентификатор клиента,обязательный
  • redirect_uri: указывает URI перенаправления, необязательно
  • scope: указывает область разрешений приложения, необязательно
  • state: Указывает текущее состояние клиента, можно указать любое значение, и сервер аутентификации вернет это значение без изменений.
Пример

Веб-сайт А предоставляет ссылку, и после того, как пользователь щелкнет ее, он перейдет на веб-сайт Б и разрешит использование данных пользователя веб-сайтом А. Ниже приведена схематическая ссылка для перехода с веб-сайта А на веб-сайт Б:

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

В URL-адресе выше:

response_typeПараметр указывает на необходимость возврата кода авторизации (code);

client_idПараметр позволяет веб-сайту B узнать, кто запрашивает;

redirect_uriПараметр — это URL-адрес перенаправления после того, как веб-сайт B примет или отклонит запрос;

scopeПараметр указывает требуемую область авторизации (здесь только для чтения).

Шаг 2

На втором этапе, после перехода пользователя, веб-сайт B попросит пользователя войти в систему, а затем спросит, согласен ли он на авторизацию веб-сайта A.

Шаг 3

Параметр Описание

На шаге 3 сервер отвечает на URI клиента со следующими параметрами:

  • code: указывает код авторизации,обязательный. Срок действия кода должен быть очень коротким, обычно устанавливается на 10 минут, и клиент может использовать код только один раз, иначе он будет отклонен сервером авторизации. Существует однозначное соответствие между этим кодом и идентификатором клиента и URI перенаправления.
  • state: если запрос клиента содержит этот параметр, ответ сервера аутентификации также должен точно содержать этот параметр.
Пример

После того, как пользователь даст согласие на шаге 2, сайт B вернется назад.redirect_uriURL-адрес, указанный параметром. При прыжке будет возвращен код авторизации, как показано ниже.

https://a.com/callback?code=AUTHORIZATION_CODE

В приведенном выше URL-адресеcodeПараметр — код авторизации.

Шаг 4

Параметр Описание

На шаге 4 клиент делает HTTP-запрос токена с сервера аутентификации, включая следующие параметры:

  • grant_type: указывает используемый режим авторизации,обязательный, значение здесь фиксируется как «authorization_code».
  • code: указывает код авторизации, полученный на предыдущем шаге,обязательный.
  • redirect_uri: указывает URI перенаправления,обязательный, и должно соответствовать значению параметра на шаге A.
  • client_id: указывает идентификатор клиента,обязательный.
Пример

На шаге 3, после того как веб-сайт A получит код авторизации, он может запросить токен с веб-сайта B на серверной части.

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

В URL-адресе выше:

client_idпараметры иclient_secretПараметр используется, чтобы позволить B подтвердить личность A (client_secretПараметры держатся в секрете, поэтому запросы можно делать только на бэкенде);

grant_typeЗначение параметраAUTHORIZATION_CODE, указывающий, что используемый метод авторизации является кодом авторизации;

codeПараметр — код авторизации, полученный на предыдущем шаге;

redirect_uriПараметр представляет собой URL-адрес обратного вызова после выдачи токена.

Шаг 5

Параметр Описание

На шаге 5 ответ HTTP, отправленный сервером аутентификации, содержит следующие параметры:

  • access_token: указывает на токен доступа, который требуется.
  • token_type: указывает тип токена. Значение не зависит от регистра и является обязательным. Это может быть тип носителя или тип mac.
  • expires_in: указывает время истечения срока действия в секундах. Если этот параметр опущен, время истечения необходимо задать другими способами.
  • refresh_token: представляет маркер обновления, который используется для получения следующего маркера доступа, необязательно.
  • scope: Указывает объем полномочий, если он соответствует объему, применяемому клиентом, этот элемент можно опустить.
Пример

На шаге 4, после того как веб-сайт B получает запрос, он выпускает токен. Конкретный подход заключается вredirect_uriУказанный URL-адрес отправляет часть данных JSON:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{    
    "access_token":"ACCESS_TOKEN",
    "token_type":"bearer",
    "expires_in":2592000,
    "refresh_token":"REFRESH_TOKEN",
    "scope":"read",
    "uid":100101,
    "info":{...}
}

В приведенных выше данных JSONaccess_tokenПоле — это токен, и веб-сайт А получает его в бэкенде. Примечание. Заголовок HTTP явно указывает, что его нельзя кэшировать.

5. Способ доставки токена

Когда клиент (стороннее приложение) получает токен для доступа к серверу ресурсов, он может использовать этот токен для доступа к ресурсам.

Получить его в стороннем приложенииaccess_token, вопрос как отправить на сервер ресурсов определен не в документе RFC6729, а как отдельныйRFC6750определяется независимо в файле. Вот краткое введение, есть три основных способа:

  1. URI Query Parameter
  2. Authorization Request Header Field
  3. Form-Encoded Body Parameter

5.1 Передача параметров заголовка запроса

Поле заголовка запроса на авторизацию, потому что в протоколе прикладного уровня HTTP специально определен заголовок запроса для авторизованного использования, поэтому этот метод также можно использовать:

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM

Где «Bearer» — фиксированная информация заголовка перед access_token.

5.2 Передача кодировки формы

Используя тело запроса таким образом, есть дополнительное требование, то есть заголовок запроса.Content-Typeдолжен быть исправленapplication/x-www-form-urlencoded, и еще одно ограничение заключается в том, чтоGET нельзя использоватьAccess, это легко понять, ведь GET-запросы не могут нести Request Body.

POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

access_token=mF_9.B5f-4.1JqM

5.3 Передача параметров запроса URI

Параметр запроса URI, который должен быть наиболее распространенным способом его использования, очень прост, например:

GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
Host: server.example.com

Просто добавьте параметр access_token к URL запрашиваемого защищенного ресурса. Другое требование заключается в том, что Клиенту необходимо установить следующий заголовок запроса.Cache-Control:no-store, который используется для предотвращения ведения журнала access_token веб-промежуточным программным обеспечением, что является соображением безопасности.

5.4 Обновление токена

Чтобы клиент не мог использовать токен неограниченное количество раз, токен обычно имеет срок действия. Когда срок его действия подходит к концу, ему необходимо повторно получить токен. Если вы проходите процесс авторизации код авторизации снова, пользовательский опыт очень плохой, поэтому OAuth 2.0 позволяет пользователям автоматически обновлять свои токены.

Конкретный метод заключается в том, что когда веб-сайт B выпускает токены, он выпускает два токена одновременно, один для получения данных, а другой для получения нового токена (поле токена обновления). До истечения срока действия токена пользователь отправляет запрос, используя токен обновления, для обновления токена.

https://b.com/oauth/token?
  grant_type=refresh_token&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET&
  refresh_token=REFRESH_TOKEN

В URL-адресе выше:

grant_typeПараметрыrefresh_tokenУказывает, что токен необходимо обновить, значение здесь фиксируется какrefresh_token,обязательный;

client_idпараметры иclient_secretПараметры используются для подтверждения личности;

refresh_tokenПараметр — это токен, используемый для обновления токена.

После проверки веб-сайта B будет выпущен новый токен.

Уведомление:Маркер обновления, полученный сторонним сервером приложений, должен храниться на сервере, а новый маркер необходимо повторно получить в фоновом режиме, чтобы обеспечить конфиденциальность маркера обновления.

Шесть, проблемы с безопасностью OAuth2

6.1 CSRF-атака

Когда приложение использовало OAuth2 в первые дни, вспыхнуло много связанных уязвимостей безопасности.На самом деле, после тщательного анализа было обнаружено, что большинство из них были вызваны нестрогим соблюдением рекомендаций OAuth2, связанных с безопасностью, и связанные с ними события уязвимости были искали сами.

На самом деле, в начале разработки OAuth2 было учтено множество соображений безопасности, и в RFC6749 были добавлены некоторые рекомендации по безопасности. Например:

  1. Требовать, чтобы сервер авторизации выполнял действительную аутентификацию клиента;

  2. Безопасное хранение конфиденциальной информации, такой как client_serect, access_token, refresh_token, код и т. д. (не должны передаваться третьим лицам), безопасность канала передачи (требуется TSL);

  3. Поддерживайте привязку между refresh_token и сторонними приложениями и обновляйте механизм отказа;

  4. Поддерживать привязку Кода авторизации и сторонних приложений, поэтому параметр состояния рекомендуется для предотвращения CSRF-атак;

  5. Гарантировать неугадываемую строку вышеуказанной информации о различных токенах, чтобы предотвратить ее угадывание;

Безопасность — дело нетривиальное, и этот аспект зависит от совместного предотвращения всех аспектов (открытая платформа, сторонние разработчики).

6.2 Процесс атаки

Предположим, что есть пользователь Чжан Сан, злоумышленник Ли Си, стороннее приложение «облачной печати» (оно интегрирует стороннюю учетную запись в социальной сети и позволяет пользователям связывать социальные учетные записи с учетными записями в «облачной печати») и поставщик услуг OAuth2. Google.

шаг 1

Злоумышленник Ли Си зашел на сайт «Облачной печати» и решил привязать свою учетную запись Google.

Шаг 2

Веб-сайт «Виртуальная печать» перенаправил Ли Си на Google.Поскольку он ранее входил в Google, Google прямо указал ему, следует ли разрешить «Виртуальной печати» доступ к странице.

Шаг 3

После того, как Ли Си нажал «Согласен на авторизацию», он перехватил контент, возвращенный сервером Google.Authorization codeПараметры ответа HTTP.

Шаг 4

Ли Си тщательно разработала веб-страницу, которая запускала бы веб-сайт «облачной печати», чтобы инициировать запрос приложения токена в Google, аAuthorization CodeПараметр — это код, перехваченный на предыдущем шаге.

Шаг 5

Ли Си разместил эту веб-страницу в Интернете и ждал или обманом заставил жертву Чжан Сана посетить ее.

Шаг 6

Чжан Сан раньше заходил на сайт «Облачная печать», но не связывал свою учетную запись с другими социальными учетными записями. Когда Чжан Сан посетил веб-страницу, подготовленную Ли Си, процесс подачи заявки на токен был успешно запущен в браузере Чжан Саня, а веб-сайт «Облачная печать» был получен от Google.access_token, но этот токен и информация о пользователе, полученная в дальнейшем через него, принадлежат злоумышленнику Ли Си.

Шаг 7

Веб-сайт «Облачная печать» связывает учетную запись Google Ли Си с учетной записью «Облачная печать» Чжан Саня. С тех пор Ли Си может использовать свою собственную учетную запись Google для входа на веб-сайт «Облачной печати» Чжан Саня через OAuth. Личность Сана для выполнения различных операций.

В целом схема последовательности этой CSRF-атаки должна выглядеть так:

Как видно из приведенного выше рисунка, ключевой момент проблемы уязвимости атаки CSRF заключается в том, что процесс аутентификации OAuth2 разделен на несколько шагов для завершения, четвертый шаг в блок-схеме в процессе режима кода авторизации в предыдущей главе, когда стороннее приложение получает запрос GET, в дополнение к знанию файла cookie текущего пользователя, а также файла cookie в URL-адресеAuthorization CodeКроме того, трудно различить, является ли запрос собственной волей пользователя или запросом, подделанным злоумышленником с использованием удостоверения пользователя.

Поэтому злоумышленник может использовать средства перемещения цветов и деревьев, чтобы заранее подготовить атаку, содержащую его собственныеAuthorization Coderequest и позволить браузеру жертвы завершить последующий процесс запроса токена.

6.3 Решения

На самом деле предотвратить такую ​​атаку очень просто: как разработчику стороннего приложения, вам нужно только добавить в процесс аутентификации OAuth.stateпараметр и проверьте его значение параметра. Конкретные детали заключаются в следующем:

  • При перенаправлении пользователя на интерфейс авторизации сервера аутентификации ресурса для текущего пользователя генерируется случайная строка, которая используется какstateПараметры добавляются к URL-адресу, а копия сохраняется в сеансе.
  • Когда стороннее приложение получает ответ, возвращенный поставщиком службы ресурсовAuthorization CodeПри запросе проверяйте полученныйstateзначение параметра. Если это правильный и законный запрос, значение параметра, полученное в это время, должно совпадать со значением, сгенерированным для пользователя, упомянутого на предыдущем шаге.stateЗначение параметра (сохраненное в сеансе текущего пользователя) точно такое же, в противном случае это ненормальный запрос.
  • stateЗначение параметра должно иметь следующие характеристики:
    • Непредсказуемость: достаточная случайность, чтобы злоумышленнику было трудно угадать правильные значения параметров.
    • Актуальность:stateЗначение параметра и текущая сессия пользователя связаны друг с другом
    • Уникальность: генерируется для каждого пользователя, даже для каждого запросаstateВсе значения параметров уникальны
    • Своевременность:stateКак только параметр используется, он сразу становится недействительным.

stateЭтот параметр не требуется в процессе аутентификации OAuth2, поэтому сторонним разработчикам приложений легко игнорировать его существование при интеграции аутентификации OAuth2 в первые дни, что делает приложение уязвимым для атак CSRF. Поэтому к этому вопросу безопасности нужно отнестись серьезно.

Безопасность важна для обеих сторон, и сторонние приложения и поставщики услуг ресурсов должны строго соблюдать спецификации безопасности. Например, в OAuth2 API QQ Internet параметр состояния является обязательным параметром, а интерфейс авторизации — зашифрованным каналом на основе HTTPS.Как стороннему разработчику, вам также следует обращать внимание на уязвимости безопасности при использовании и потреблении эти услуги.

Семь, справочные материалы и кейсы OAuth2

7.1 Ссылки

oauth.net/2/

Oauth Status Pages

RFC6749 : The OAuth 2.0 Authorization Framework

RFC6749 китайская версия

7.2 Случаи

Douban OAuth2 API (код авторизации)

QQ OAuth2 API (код авторизации)

API Douban OAuth2 (неявный)

API QQ OAuth2 (неявный)

Официальный аккаунт Wechat для получения access_token (предоставление учетных данных клиента)

Документация по разработке Weibo: механизм авторизации

Справочная запись в блоге:

Четыре способа OAuth 2.0

Понимание OAuth 2.0

Простое объяснение OAuth 2.0

Аутентификация и авторизация OAuth2

Общие сведения об аутентификации OAuth2.0 и подробностях режима кода авторизации клиента

Охват: атаки на OAuth2

Авторизация OAuth и атака CSRF

OAuth Research & Study Notes

личный блог:woodwhale's blog

Блог Сад:Блог деревянного кита