Авторизация через oauth приложение облако для android
Разбираемся, как работает протокол OAuth 2.0 и OpenID Connect. Почему Authorization Code Grand лучший способ получения access token.
Если коротко OAuth 2.0 — протокол авторизации, позволяющий выдать одному сервису (приложению) права на доступ к ресурсам пользователя на другом сервисе. Протокол избавляет от необходимости доверять приложению логин и пароль, а также позволяет выдавать ограниченный набор прав, а не все сразу.
В этой статье рассмотрим историю возникновения и схему работы. Разберемся в чем отличие OAuth 2.0 от OpenID Connect и что такое SSO.
История возникновения OAuth
Авторизацией через социальные сети никого уже не удивишь. Нажимаешь кнопку соц сети, вжух и ты авторизовался на новом сайте. Сайт получил твоё ФИО, фотку и прочие данные. Но так было не всегда.
В «каменном веке» интернета все было проще. Вы просто давали свой логин и пароль от одного сервиса другому, чтобы тот вошел в вашу учетную запись и получил любую необходимую ему информацию.
С помощью этого стандарта вы позволяете приложению считать данные или использовать функции другого приложения от вашего имени, не сообщая ему свой пароль. Класс!
OAuth 1.0 не используется. Забудьте о нем. Используйте OAuth 2.0
Главным недостатком OAuth 1.0 была слишком большая сложность данной версии.
Начнем разбор OAuth 2.0 с ролей. Всего есть 4 роли:
- Владелец ресурса.
- Клиент.
- Сервер ресурсов.
- Авторизационный сервер.
Далее мы рассмотрим каждую из ролей.
Сервер ресурсов
На сервере ресурсов лежат ваши данные. В случае с примером выше ваши контакты Gmail это ресурс, а лежат они на серверах Gmail.
Клиент
Клиент это сервис, которому требуется доступ к вашим ресурсам. Например, Facebook требуется доступ к контактам Gmail.
Авторизационный сервер
В данном примере он принадлежит Google, так как он хранит ваши данные.
Стандарт не запрещает вам объединить Сервер ресурсов и Авторизационный сервер
Базовая схема протокола
Вернемся к нашему примеру про Facebook и Gmail. На анимации ниже, я постарался схематично изобразить, как реализовать этот пример правильно с помощью Oauth2. Стоит учитывать, что у Google есть свой сервер авторизации, который отвечает за авторизацию на любом сервисе Google. Поэтому Gmail только хранит ресурсы, но не отвечает за авторизацию.
Весь смысл в том, что Клиент должен получить каким-то образом от авторизационного сервера access_token . Способов этих четыре, о них мы поговорим дальше. Используя этот access_token Клиент может использовать его в запросах к Серверу ресурсов, чтобы получать какие-то данные.
Это строка, которая является альтернативой логину и паролю.
Особенности Access Token:
- Ограниченное время жизни.
- Его можно отозвать. Если есть подозрение, что токен украли, то мы просто запрещаем получать данные с помощью этого токена.
- Компрометация токена не значит компрометирование логина и пароля. Из токена никак не получить логин и пароль.
- По токену может быть доступна только часть данных (scope). Клиент запрашивает список разрешений, которые необходимы ему для работы, а Владелец ресурсов решает выдать такие права или нет. Например, можно выдать права только на просмотр списка контактов, тогда читать письма или редактировать контакты будет нельзя.
Помимо access_token Авторизационный сервер может выдавать также refresh_token. Это токен, который позволяет запросить новый access_token без участия Владельца ресурсов. Время жизни у такого токена намного больше access_token и его потеря гораздо серьезнее.
Не все клиенты могут гарантировать сохранность client_secret , поэтому он есть не у всех. Например, SPA без бэкенда, теоретически достать оттуда можно что угодно.
Существует возможность регистрировать клиентов динамически: RFC 7591 и RFC 7592.
Способы получения Access Token
Всего есть 4 способа:
- По авторизационному коду (Authorization Code Grand). Самый сложный и самый надежный способ.
- Неявно (Implicit)
- По логину и паролю пользователя (Resource Owner Password Credential). Только для безопасных клиентов, заслуживающих полного доверия.
- По данным клиента (Client Credentials). Получаем токен по client_id и client_secret .
Client Credentials
Начнем разбор с самой простой схемы. Этот способ придуман для межсерверного взаимодействия. У нас есть два сервера API1 и API2, и им надо как-то общаться.
2. Взамен API 1 получает access_token , с помощью которого может обратиться к API 2.
3. API 1 обращается к API 2.
4. API 2 получает запрос с access_token и обращается к авторизационному серверу для проверки действительности переданного токена (RFC 7662).
Resource Owner Password Credential
Эта схема не рекомендуется к использованию! В стандарте так и написано, если вы никакие другие схемы не можете сделать, то используйте эту.
- Владелец ресурсов передает свой логин и пароль Клиенту.
- Клиент отправляет Авторизационному серверу логин и пароль клиента, а так же свой client_id и client_secret .
3. Если предоставленные пользователем учетные данные успешно аутентифицированы, сервер авторизации вернет ответ application/json , содержащий access_token :
Authorization Code Grand
Является одним из наиболее распространённых типов разрешения, поскольку он хорошо подходит для серверных приложений, где исходный код приложения и секрет клиента не доступны посторонним.
Этот способ рекомендуемый. Используйте его, и только если это невозможно, посмотрите на другие способы. Исключением является межсерверное общение.
- Пользователь на сайте нажимает кнопку авторизации, например через Facebook.
- Происходит редирект на авторизационный сервер.
- Если активной сессии нет, то Пользователь должен залогиниться. Если активная сессия есть, то просто подтвердить авторизацию.
Пример авторизационного запроса
- response_type - Обозначает тип учетных данных, которые возвращает авторизационный сервер. Для этого способа значение должно быть code .
- redirect_uri - URL-адрес, на который авторизационный сервер будет перенаправлять браузер после авторизации пользователя. Код авторизации будет доступен в параметре code .
Так как code попадает в браузер и ничем не защищен, то это точка уязвимости. Поэтому на авторизационный код накладываются следующие ограничения:
- Код одноразовый
- Время жизни кода очень мало
5. Теперь, когда у вас есть код авторизации, вы должны обменять его на токены. Используя извлеченный код авторизации из предыдущего шага, вам нужно будет выполнить POST на URL-адрес токена.
Implicit Grant
Теперь у нас сайт без бэкенда - SPA.
Так как access_token попадает в браузер, то существует возможность его достать.
OpenID Connect
OAuth 2.0 разработан только для авторизации — для предоставления доступа к данным и функциям от одного приложения другому. OpenID Connect (OIDC) — это тонкий слой поверх OAuth 2.0, добавляющий сведения о логине и профиле пользователя, который вошел в учетную запись.
OpenID Connect позволяет реализовывать сценарии, когда единственный логин можно использовать во множестве приложений, — этот подход также известен как single sign-on (SSO)
Поток (flow) OpenID Connect выглядит так же, как и в случае OAuth 2.0. Единственная разница в том, что в первичном запросе используемый конкретный scope — openid, — а Клиент в итоге получает как access_token , так и id_token .
ID Token — это особым образом отформатированная строка символов - JSON Web Token или JWT. Сторонним наблюдателям JWT может показаться непонятной абракадаброй, однако Клиент может извлечь из JWT различную информацию, такую как ID, имя пользователя, время входа в учетную запись, срок окончания действия ID Token’а, наличие попыток вмешательства в JWT.
Эта статья посвящена детальному разбору JWT и его возможностей. Мы изучим структуру токена и построим его с нуля. Затем рассмотрим наиболее распространенные способы использования.В случае OIDC также имеется стандартный способ, с помощью которого Клиент может запросить дополнительную информацию о пользователе от Сервера авторизации, например, адрес электронной почты, используя access_token .
Заключение
Чтобы получить доступ к некоторым онлайн-сервисам, пользователям нужно пройти аутентификацию. Обычно он вводит свой логин и пароль в браузере. Если вы создаёте своё приложение, которое будет подключаться к такому сервису, то не только пользователь должен пройти аутентификацию для доступа к сервису в вашем приложении, но и приложение должно быть авторизовано для выполнения действий от имени пользователя.
На данный момент стандартным протоколом для аутентификация является OAuth2 (Open Authorization). OAuth2 обеспечивает единственное значение, называемое токен авторизации (Auth Token), который представляет как пользователя, так и авторизованное приложения, которое будет действовать от имени пользователя.
Протокол используют Twitter, Google, Flickr, Digg, Yahoo и многие другие сервисы.
Необходимо понимать разницу между терминами аутентификация (authentication) и авторизация (authorization).
Аутентификация - вы посещаете режимное предприятие и показываете своё удостоверение. Охранник смотрит и принимает решение: удостоверение настоящее? печать на месте? фотка совпадает? Опытный охранник может узнать вас в лицо и пропустить и так. Аутентификация может быть простой, а может быть и сложной.
На сайтах обычно аутентификация происходит по схеме логин/пароль, заставляя пользователя вводить данные и проверяя их на сервере.
Авторизация наступает после успешной аутентификации. Даже если вы показали настоящее удостоверение, у вас может быть запрет на посещение отдельных этажей, комнат, серверной и т.д. Или вы не можете пройти в здание по выходным.
Использование OAuth2 подходит для:
- Получения разрешения от пользователя для доступа к онлайн-службе с помощью своей учетной записи.
- Аутентификация на онлайн-сервисе от имени пользователя.
- Обработка ошибок аутентификации.
Чтобы начать использовать OAuth2, вы должны знать:
- 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
Теперь вы готовы запрашивать токен авторизации. Это многоступенчатый процесс.
Для получения токена авторизации необходимо сначала запросить права на использование ACCOUNT_MANAGER в манифесте. Не забываем про разрешение на интернет.
Имея необходимые полномочия, вы можете вызвать AccountManager.getAuthToken() для получения токена. Большинство методов AccountManager – асинхронные. Вам придётся реализовать её в виде серии обратных вызовов, например:
В этом примере класс OnTokenAcquired расширяет AccountManagerCallback. AccountManager вызывает run() в OnTokenAcquired с AccountManagerFuture, содержащим Bundle. Если вызов успешен, то токен будет внутри Bundle.
Вы можете получить токен из Bundle:
Если все пойдёт хорошо, то Bundle будет содержать допустимый токен в ключе KEY_AUTHTOKEN. Но не всегда все идёт так как запланированно.
Ваш первый запрос токена авторизации может завершиться неудачей по нескольким причинам:
- Ошибка в устройстве или сети вызвала сбой AccountManager.
- Пользователь решил не предоставлять вашему приложению доступ к аккаунту.
- Сохраненных полномочий аккаунта не хватает для получения доступа к аккаунту.
- Кэшированный токен авторизации истек.
Третий случай неудачи, имеющий недостаточные полномочия, передается через Bundle, который вы получаете в вашем AccountManagerCallback (OnTokenAcquired из предыдущего примера). Если Bundle включает Intent в ключе KEY_INTENT, то аутентификатор говорит вам, что ему необходимо прямое взаимодействие с пользователем, прежде чем он может дать вам действительный токен.
У аутентификатора может быть много причин для возврата Intent. Это может быть первый вход пользователя в эту учетную запись. Возможно время учетной записи пользователя истекло и требуется повторный вход в систему или сохраненные полномочия неверны. Может быть аккаунт требует двухфакторной аутентификации либо требуется включение камеры для сканирования сетчатки. В действительности причина не имеет значения. Если вы хотите действительный токен, вы должны обратиться к Intent, чтобы получить его.
Обратите внимание, что пример использует startActivityForResult(), и вы можете перехватить результат Intent в методе onActivityResult() в вашей активности. Если вы не станете перехватывать результат ответа Intent аутентификатора, невозможно будет определить прошёл ли пользователь проверку подлинности или нет. Если результат RESULT_OK, то аутентификатор обновил сохранённые полномочия, чтобы они были достаточны для доступа который вы запросили, далее вы должны вызвать AccountManager.getAuthToken() снова и запросить новый токен аутентификации.
Последний случай, когда токен истёк, на самом деле не ошибка AccountManager. Единственный способ выяснить действительно ли токен истек – это связаться с сервером, что было бы расточительным и дорогим со стороны AccountManager постоянно выходить в интернет и проверять состояние всех своих токенов. Так что эта неудача может быть обнаружено только когда приложение пытается использовать токен аутентификации для доступа к веб сервису.
Подключение к онлайн-сервисам
Пример ниже показывает, как подключиться к серверу Google. Так как Google использует стандарт протокола OAuth2 для проверки подлинности запросов, методы, обсуждаемые здесь широко применимы. Имейте в виду, что каждый сервер отличается. Вам может понадобиться внести небольшие изменения в этот пример для учета вашей конкретной ситуации.
Атака возможна из-за ошибки в реализации протокола аутентификации OAuth 2.0.
Группа специалистов из Университета Гонконга продемонстрировала новый метод, позволяющий удаленно получить доступ к любой учетной записи в Android- и iOS-приложениях без ведома жертвы.
В рамках исследования эксперты проанализировали 600 наиболее популярных в США и Китае Android-приложений, 182 из которых поддерживали технологию единого входа (Single Sign-On). В 41% приложений исследователи обнаружили проблему, связанную с реализацией протокола авторизации OAuth 2.0. Данный протокол, позволяющий реализовать безопасную аутентификацию пользователей, предоставляет возможность подписчикам Google, Facebook, Microsoft или Twitter получить доступ из своих учетных записей на другие web-сайты.
При использовании OAuth 2.0 для авторизации в стороннем приложении, программа обращается к ID-провайдеру (скажем, Facebook) для верификации данных аутентификации. В случае, если информация достоверна, Facebook отправляет маркер доступа (Access Token), который затем передается на сервер мобильного приложения. В результате пользователь может авторизоваться в приложении, используя учетные данные Facebook.
Как оказалось в ходе анализа, в огромном числе Android-приложений некорректно реализован механизм, проверяющий наличие взаимосвязи между пользователем и ID-провайдером. То есть, сервер проверяет только идентификатор пользователя. Как поясняют эксперты, злоумышленники могут удаленно загрузить уязвимое приложение, авторизоваться при помощи собственных учетных данных, а затем изменить логин на имя пользователя жертвы при помощи сервера, способного модифицировать данные, отправленные Facebook, Google или другими сервисами. Таким образом атакующие могут получить доступ ко всем данным в приложении.
Например, хакеры могут взломать приложения для планирования путешествий или бронирования гостиничных номеров и получить доступ к планировщику жертвы, оплатить номер в отеле или похитить персональную информацию, такую как данные банковского счета или адрес проживания.
Каждый запрос, отправляемый вашим приложением в Google My Business API, должен содержать токен авторизации. Этот токен идентифицирует пользователя или приложение сервисам Google, что необходимо для доступа к Google My Business API. В вашем приложении для авторизации запросов должен использоваться протокол OAuth 2.0.
Реализация OAuth 2.0 позволяет получить следующие преимущества:
- Защита доступа к данным владельца компании.
- Аутентификация владельца компании при входе в его аккаунт Google.
- Проверка прав партнерской платформы или приложения получать или изменять данные об адресах с явного согласия владельца компании. Владелец компании может отозвать эти права.
- Аутентификация партнерской платформы.
- Возможность партнерской платформы выполнять онлайн- и офлайн-действия от имени владельца компании: отвечать на отзывы, создавать публикации, обновлять меню и т. п.
Доступ к API с помощью OAuth 2.0
Прежде чем начинать работу, вам понадобится создать проект Google Cloud и включить Google My Business API. Подробнее об этом рассказывается в руководстве по базовой настройке.
Настройка OAuth и окна для получения согласия пользователей
Чтобы создать учетные данные и настроить окно для получения согласия пользователей, выполните следующие действия:
- На странице "Учетные данные" в API Console нажмите Создать учетные данные и выберите "Идентификатор клиента OAuth" в раскрывающемся списке.
- Выберите тип своего приложения, укажите необходимую информацию и нажмите Создать.
- Нажмите Сохранить.
- Обновите Настройки окна OAuth для получения согласия пользователей. Здесь вы можете изменить название приложения и его логотип, а также добавить ссылку на условия использования и политику конфиденциальности своего сервиса.
На следующем рисунке показаны поля "Название приложения" и "Логотип приложения" окна OAuth для получения согласия пользователей:
На следующем рисунке показаны дополнительные поля окна OAuth для получения согласия пользователей:
На следующем рисунке показан пример окна, которое увидит пользователь:
Способы внедрения OAuth 2.0
Для внедрения OAuth 2.0 можно использовать следующие технологии и инструменты:
Далее в этой статье приводится подробное описание каждого способа внедрения OAuth 2.0 в приложение.
Область авторизации
В качестве области авторизации OAuth необходимо указать одно из следующих значений:
Область plus.business.manage более не поддерживается. Она остается доступной, чтобы обеспечить обратную совместимость существующих решений.
Клиентские библиотеки
В приведенных здесь примерах для конкретных языков программирования показана реализация OAuth 2.0 с помощью клиентских библиотек Google API. Чтобы выполнить код из примера, сначала необходимо установить клиентскую библиотеку для соответствующего языка.
Клиентские библиотеки доступны для следующих языков:
Автономный доступ
Вам может потребоваться совершать вызовы Google My Business API от имени пользователя, даже когда он не в сети. Внедрение этой функции рекомендуется для всех платформ. Поскольку тогда вы сможете управлять информацией о компаниях (например, изменять и просматривать ее) в любое время после того, как пользователь вошел в аккаунт и предоставил вам полномочия.
В приведенном ниже примере кода показано, как реализовать автономный доступ в приложении. О том, как выполнить этот код, рассказывается здесь.
Только онлайн-доступ
Чтобы упростить реализацию, можно совершать вызовы Google My Business API без кеширования токенов обновления. Впрочем, тогда платформа сможет совершать вызовы от имени пользователя, только если этот пользователь вошел в свой аккаунт и сейчас присутствует в сети.
В приведенном ниже примере кода показано, как реализовать поддержку входа с аккаунтом Google и как совершить вызов API от имени конкретного пользователя. После того как пользователь совершает вход, используя свой аккаунт Google, и предоставляет согласие вашему приложению, вы получаете токен доступа. Этот токен доступа является идентификатором пользователя. Токен нужно указать в заголовке запроса Google My Business API.
О том, как выполнить этот код, рассказывается здесь.
Выполнение кода из примера
Чтобы выполнить код из приведенного здесь примера, сделайте следующее:
-
Сохраните фрагмент кода в файле с названием index.html . Укажите в этом файле свой идентификатор клиента.
Запустите веб-сервер из своего рабочего каталога со следующей командой:
Python 2.X
Python 3.X
На странице Учетные данные в API Console выберите используемый идентификатор клиента.
Загрузите следующий URL в браузере:
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Читайте также: