Аутентификация через OAuth2 сервисы (Authenticating to OAuth2 Services)


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

Промышленный стандарт – аутентификация со сторонними сервисами по протоколу OAuth2. OAuth2 обеспечивает единственное значение, называемое токен авторизации (Auth Token), который представляет как пользователя так и авторизованное приложения, которое будет действовать от имени пользователя. Этот урок демонстрирует подключение к серверу Google, поддерживающему OAuth2. Хотя в качестве примера и используются сервисы Google, продемонстрированные методы будут работать и для друних сервисов, правильно поддерживающих протокол OAuth2.

Использование OAuth2 подходит для:

  • Получения разрешения от пользователя для доступа к онлайн службе с помощью своей учетной записи.
  • Аутентификация на онлайн сервисе от имени пользователя.
  • Обработка ошибок аутентификации.

Сбор информации

Чтобы начать использовать OAuth2, вы должны знать кое-что о API, к которому вы пытаетесь получить доступ:

  • URL сервиса, к которому вы хотите получить доступ.
  • Рамки аутентификации (auth scope), которые являются строкой, определяющей конкретный тип доступа, запрашиваемый вашим приложением. Например, запрос доступа только для чтения к Google Tasks – это View your tasks, в то время как доступ для чтения и записи к Google Tasks – это Manage Your Tasks.
  • Идентификатор клиента (client id) и “секрет” клиента (client secret) – это строки, которые идентифицируют ваше приложение на сервисе. Вы должны получить эти строки непосредственно у владельца сервиса. Google имеет систему самообслуживания для получения идентификаторов клиента и секретов. Статья Getting Started with the Tasks API and OAuth 2.0 on Android объясняет, как использовать эту систему, чтобы получить эти значения для использования c Google Tasks API.

Запрос Auth Token

Теперь вы готовы запрашивать токен авторизации. Это многоступенчатый процесс.

oauth_dance

Для получения токена авторизации необходимо сначала запросить права на использование ACCOUNT_MANAGER в вашем файле манифеста. Чтобы действительно сделать что-нибудь полезное с токеном, вы должны добавить разрешение на использование INTERNET.

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

Осторожно! Вызов методов AccountManager может быть запутанным! Поскольку операции с аккаунтом могут быть связаны с сетью, большинство из методов AccountManager – асинхронные. Это означает, что вместо того чтобы делать всю работу по авторизации в одной функции, вам придется реализовать ее в виде серии обратных вызовов. Например:

В этом примере класс OnTokenAcquired расширяет AccountManagerCallback. AccountManager вызывает run() вOnTokenAcquired с AccountManagerFuture, содержащим Bundle. Если вызов успешен, то токен будет внутри Bundle.

Вот так вы можете получить токен из Bundle:

Если все пойдет хорошо, то Bundle будет содержать допустимый токен в ключе KEY_AUTHTOKEN и вы добьетесь. Но не всегда все идет так как запланированно…

Запрос Auth Token снова

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

  • Ошибка в устройстве или сети вызвала сбой AccountManager.
  • Пользователь решил не предоставлять вашему приложению доступ к аккаунту.
  • Сохраненных полномочий аккаунта не хватает для получения доступа к аккаунту.
  • Кэшированный токен авторизации истек.

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

Третий случай неудачи, имеющий недостаточные полномочия, передается через Bundle, который вы получаете в вашемAccountManagerCallback (OnTokenAcquired из предыдущего примера). Если Bundle включает Intent в ключе KEY_INTENT, то аутентификатор говорит вам, что ему необходимо прямое взаимодействие с пользователем, прежде чем он может дать вам действительный токен.

У аутентификатора может быть много причин для возврата Intent. Это может быть первый вход пользователя в эту учетную запись. Возможно время учетной записи пользователя истекло и требуется повторный вход в систему или сохраненные полномочия неверны. Может быть аккаунт требует двухфакторной аутентификации либо требуется включение камеры для сканирования сетчатки. В действительности причина не имеет значения. Если вы хотите действительный токен, вы должны обратиться к Intent, чтобы получить его.

Обратите внимание, что пример использует startActivityForResult(), так что вы можете перехватить результат Intent в реализации onActivityResult() в вашей activity. Это важно! Если вы не перехватите результат ответа Intent аутентификатора, невозможно будет определить прошел ли пользователь проверку подлинности или нет. Если результат RESULT_OK, то аутентификатор обновил сохраненные полномочия, чтобы они были достаточны для доступа который вы запросили, далее вы должны вызвать AccountManager.getAuthToken() снова запросить новый токен аутентификации.

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

Подключение к Online сервисам

Пример ниже показывает, как подключиться к серверу Google. Так как Google использует стандарт протокола OAuth2 для проверки подлинности запросов, методы, обсуждаемые здесь широко применимы. Имейте в виду, что каждый сервер отличается. Вам может понадобиться внести небольшие изменения в этот пример для учета вашей конкретной ситуации.

Google API требует предоставления четырех значений с каждым запросом: API key, client ID, client secret, и auth key. Первые три получаются на сайте Google API Console. Последнее значение вы получаете вызвавAccountManager.getAuthToken(). Вы передаете их на сервер Google в качестве части HTTP запроса.

Если запрос возвращает HTTP ошибку 401, то ваш токен был отклонен. Как уже упоминалось в предыдущем разделе, самая распространенная причина этого – истечение токена. Исправить это просто: вызовитеAccountManager.invalidateAuthToken() и повторите запрос токена еще раз.

Так как истечение токена является обычным явлением и исправление этой ситуации достаточно легкое, многие приложения просто предполагают истечение токена еще до того как станет известно об этом. Если обновление токена дешевая операция для вашего сервера, вы можете вызывать AccountManager.invalidateAuthToken() перед первым вызовомAccountManager.getAuthToken() и избавить себя от необходимость запрашивать токен аутентификации два раза.

 

Источник

Перевод kraY

Оставьте комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *