Ключевые слова: аутентификация, протокол авторизации, токен доступа, уровень доступа, мобильное приложение, файл, файл настроек, база данных, менеджер учетных записей.
В наши дни различные онлайн-сервисы имеют разные способы обработки учетных записей и аутентификации. Многие из них построены на протоколе OAuth.
OAuth — открытый протокол авторизации, который позволяет предоставить третьей стороне ограниченный доступ к защищённым ресурсам пользователя без необходимости передавать ей логин и пароль [1]. Вместо передачи логина и пароля используется токен доступа.
Токен доступа — это уникальная последовательность символов, однозначно идентифицирующая пользователя. Зная эту последовательность, можно получить доступ к информации владельца токена.
Рис. 1. Получение токена доступа
Алгоритм взаимодействия Андроид приложения с веб-сервером (Рис. 1) для получения токена доступа выглядит следующим образом:
- Перенаправление пользователя на окно авторизации;
- Авторизация пользователя с мобильного приложения (заполнение формы);
- Запрос подтверждения прав на сервере;
- Перенаправление сервером на принимающую страницу;
- Мобильное приложение запрашивает токен доступа;
- Сервер выдает токен доступа приложению.
Имея токен доступа, мобильное приложение может получать информацию пользователя не отправляя логин и пароль при каждом запросе на удаленный сервер. Это говорит о важности токена для пользователя и важности его хранения.
Операционная система Андроид предоставляет несколько инструментов для хранения данных:
- Shared preferences;
- Сохранение в файл;
- База данных;
- Account manager.
Shared preferences (файл общих настроек) представляет из себя хранилище данных, позволяющее хранить примитивные типы данных (целочисленные значения, строковые значения, символы, булевы переменные). Хранение производится по принципу «Ключ:Значение». Операционная система Андроид предоставляет инструменты, необходимые для чтения и записи данных в файл общих настроек.
Создавая/открывая файл общих настроек, необходимо указать уровень доступа:
- MODE_PRIVATE — файл созданный в данном режиме может использоваться только в создавшем его приложении (используется как режим по умолчанию);
- MODE_WORLD_READABLE — файл, созданный/открытый в этом режиме доступен для чтения для любого приложения;
- MODE_WORLD_WRITABLE — файл, созданный/открытый в этом режиме доступен для редактирования для любого приложения;
- MODE_MULTI_PROCESS — файл, созданный/открытый в этом режиме может использоваться одновременно несколькими потоками.
Режим MODE_PRIVATE является наиболее безопасным из всех представленных. Он дает доступ к файлу только одному приложению, которое его создало. Файл закрыт для внешних приложений, даже если они были написаны тем же разработчиком.
Режимы MODE_WORLD_READABLE и MODE_WORLD_WRITABLE не являются безопасными, так как дают доступ к файлу любому другому приложению.
Режим MODE_MULTI_PROCESS так же не является безопасным, так как дает возможности многопоточного программирования, что дает одновременный доступ к файлу с нескольких мест одного приложения, либо с нескольких приложений.
Общий файл настроек позволяет хранить данные безопасно для одного приложения, но при этом он не защищен от декомпиляции установочного APK файла. После декомпиляции файла можно получить доступ к файлу настроек и поменять режим доступа.
Альтернативным способом хранения данных в файле является обычный файл. Его отличие от Shared Preferences состоит в том, что данные в нем хранятся в свободном виде, т. е. файл представляет из себя одну строку. Для хранения множества значений можно создать несколько файлов или продумать структуру, которая позволит хранить несколько значений.
Данный способ хранения является небезопасным, так как после инициализации файла в коде, он будет создан в хранилище телефона или на карте памяти пользователя. Файл будет доступен всем приложениям на телефоне. Человек, получивший доступ к мобильному телефону, может получить данный файл, скопировав его с телефона.
Еще один способ хранения данных — база данных. База данных — хранилище, которое подходит для структурированных данных.
Чтобы записать токен доступа в базу данных необходимо проделать следующие шаги:
- Инициализировать базу данных;
- Инициализировать схему для базы данных;
- Создать таблицу;
- Сохранить запись.
Хранение в базе данных безопасно, но это очень ресурснозатратный процесс. Нужно инициализировать целую базу данных для хранения строкового значения. Это малоэффективно с точки зрения использования памяти.
Последний способ хранения данных — менеджер учетных записей. Менеджер учетных записей — это класс, предоставляющий централизованный доступ к реестру сетевых учетных записей пользователя. В данный реестр однажды вносятся необходимые данные, далее пользователь получает доступ к аккаунту с одобрением в один клик.
Различные онлайн-сервисы имеют разные способы обработки учетных записей и аутентификации, поэтому менеджер учетных записей использует подключаемые модули аутентификации для разных типов учетных записей. Серверы аутентификации обрабатывают фактические данные проверки учетных данных и хранения информации об учетной записи.
Многие серверы поддерживают понятие токена аутентификации, который можно использовать для аутентификации запроса к серверу без отправки действительного пароля пользователя. Токены аутентификации обычно создаются с помощью отдельного запроса, который включает учетные данные пользователя. Менеджер учетных записей может генерировать токены аутентификации для приложений, поэтому приложению не нужно обрабатывать пароли напрямую. Токены аутентификации можно использовать повторно и кэшировать с помощью менеджера учетных записей.
Таким образом, хранение данных в менеджере учетных записей наиболее безопасно на сегодняшний день. Доступ к данным, сохраненным в менеджере учетных записей, имеется у многих приложений, но получить его можно только после согласия пользователя. Эти данные невозможно получить после декомпиляции APK файл, так как менеджер учетных записей не привязан к одному приложению, он контролируется операционной системой Андроид.
Литература:
- E. Hammer-Lahav, Ed. The OAuth 1.0 Protocol // IETF. — 2010. — April. — ISSN 2070–1721, 1 p.