Django allauth авторизация через социальную сеть | VIVAZZI
Выход: а что это такое
В современных приложениях на смартфоне сложно найти кнопку или значок для выхода, а зачастую это вообще невозможно. На компьютере обычно есть параметр «Выход», но многие пользователи никогда не используют эту возможность. Один раз зашли и больше никогда не выходят. Это хорошо, если техника всегда работает, никогда не подводит, либо не нужно заводить второй аккаунт на сайте.
Что такое регистрация
Регистрация – это необходимый этап для того, чтобы пользователь получил доступ к тем возможностям, которые предоставляются на каком-либо интернет-ресурсе. Регистрацию проходят только один раз (в идеале). После того, как человек ее прошел, ему становятся доступны те возможности, которые имеются на данном ресурсе.
Что случилось?
Здравствуй, дорогой читатель. Если тебе хотя бы однажды доводилось работать с API Вконтакте и при этом писать все на python, вероятно, авторизация приложения заставила тебя сделать несколько приседаний, после которых ног либо не чувствуешь и падаешь в обморок, либо вкачиваешь квадрицепс и все же пробиваешь API, как Ван Дамм.
По какой-то причине этот, казалось бы, самый непримечательный этап поначалу отнимает огромное количество сил и времени. Моя задача: помочь читателям Хабра избежать травм ног.
Далее я предлагаю рассмотреть небольшую библиотеку, позволяющую в одну строчку авторизовать свое приложение для конкретного пользователя и получить access_token. В конце статьи представлена ссылка на github-репозиторий этой библиотеки с quickstart’ом в README-файле.
10 Как реализовать меж-доменную идентификацию?
Всё это, конечно, хорошо. Пока работа осуществляется на одном браузере – всё отлично. А как быть с современными реалиями, когда у человека два мобильных телефона, один рабочий компьютер и несколько браузеров на нем, домашний компьютер, и ещё ноутбук?
Придется как-то решать вопрос с переносом ключей доменов между браузерами, устройствами. А ещё решить вопрос их правильной синхронизации.
Одним из механизмов решения данной задачи является вычисление различных ключей доменов на базе общего мастер-ключа без возможности обратного восстановления мастер-ключа по известному ключу домена.
Создав при помощи мастер-ключа M персональный ключ K для домена D на одном устройстве, пользователь сможет создать тот же самый ключ K для домена D и на любом другом при помощи всё того же мастер-ключа M и единого алгоритма. Точнее это сделает не пользователь, а его браузер.
Максимальное удобство для пользователя.
Но и максимальный риск
в случае компрометации мастер-ключа. Поэтому последний должен защищаться соответствующим образом. О рисках утраты или компрометации мастер-ключа, о способах минимизации таких рисков написано в главе
Использование только одного мастер-ключа для генерации всех ключей для всех доменов не всегда удобный вариант. Во-первых, как быть, если вдруг ключ домена скомпрометирован и его необходимо поменять? Во-вторых, что если нужно поделиться ключом домена с другим человеком?
Поэтому генерация индивидуальных ключей доменов при помощи биологического датчика случайных чисел должна поддерживаться браузерами. Но тогда мы вновь возвращаемся к вопросу нашей мобильности и вопросам синхронизации, функций экспорта и импорта ключей в браузере, создания резервных копий.
2 Структура токена
Токен представляет собой 256-битную структуру, представляемую в виде шестнадцатеричной строки:
4 Как происходит идентификация клиентов сайтами?
Сайт может использовать токен для идентификации посетителя сайта. При этом схема генерации токенов и их 256-битная разрядность
гарантирует уникальность токенов для каждой пары:
пользователь-домен. Другой домен будет видеть уже другой токен пользователя. Даже если исполняется в контексте целевого сайта (через IFRAME, IMG, LINK, SCRIPT). Кроме того, специальный алгоритм генерации токенов защищает пользователей от атак XSS, СSRF и делает невозможным трекинг пользователя без его ведома. Но при этом оставляет возможным технологию
SSO
с его разрешения и меж-доменную идентификацию.
Токен
5 Как происходит авторизация клиентов сайтами?
Важно понимать, что токен ещё не делает пользователя авторизованным на конкретном сайте, – только узнаваемым. Но, как уже было ранее сказано, для него вы пока – просто узнаваемый «аноним».
Если сайту необходимо связать ваш токен с вами лично, регистрации на таком сайте, увы, не избежать. Но в предлагаемом протоколе это делается чуть проще.
Разработчикам важно понимать: анкета не обязательно нужна большинству сайтов. Избегайте принуждения посетителей к обязательной регистрации. В большинстве типовых ситуаций вы можете осуществить бизнес-процесс без сбора ПДн посетителей.
6 А как реализовать надежную идентификацию клиентов?
В более серьезных ситуациях (личный кабинет провайдера, хостинга, банка) должна и может осуществляться двухфакторная аутентификация, а доказательство обладанием токена производиться через предварительную регистрацию и подтверждение личности иными способами: по электронной почте, СМС, или даже бумажной фиксацией токена пользователя. (Да, да. Сертификаты фиксируются бумажными носителями, почему бы и токенам не быть).
7 Авторизация на сайте глазами пользователя
Браузер уведомляет пользователя, что сайт поддерживает авторизацию CSI, через иконку замка в адресной строке. Если вы совершаете на сайте некоторые действия, вы можете попросить сайт запомнить вас. С этого момента сервер будет узнавать пользователя даже между разными сессиями:
Вместо фиксации ключа, пользователь может создать постоянный ключ для сайта и пройти там регистрацию. Анимированная иллюстрация:
А когда пользователь имеет постоянный ключ для сайта и этот ключ там зарегистрирован, то процесс входа существенно упрощается:
Наибольшая сила протокола проявляется, когда пользователь создает ключ для сайта на базе мастер-ключа. В этом случае легко
решается задача вашей идентификации на сайтах на других устройствах
. Следующая анимация демонстрирует это. Предполагается, что вы предварительно однажды распространили свой мастер-ключ между своими устройствами / браузерами:
Для сайтов с двух-факторной авторизацией «узнавание» может выглядеть так:
Выход осуществляется ещё проще. Нажимаете в браузере «Выйти» и всё:
Браузер посылает сайту запрос (на любую его страницу) с методом HEAD, в котором передает заголовок CSI-Token <>; Logout.
Сервер, видя такой заголовок, делает Logout. Если это был фиксированный ключ, то сайт удаляет всю информацию о пользователе (более такой ключ никогда не появится). Если это был постоянный ключ, просто разрывает сессию.
8 Как происходит смена ключа сайта?
Замена постоянного ключа сайта технически происходит также, как и переход со случайного ключа на постоянный. Более подробнее это описано в
В случае смены постоянного ключа сайта, браузер уведомляет сайт о соответствующем изменении токена, посылая
в каждом последующем запросе
заголовок
CSI-Token
с ключом
Changed-To
Сайт должен корректно обработать такой запрос. И, если данный токен пользователя сохранен в его базе, должен сделать соответствующую замену. При этом сайт должен ответить браузеру об успешном изменении токена на своей стороне. Делает он это в заголовке ответа (Response Headers) параметром:
CSI-Token-Action: success
, с указанием примененного токена.
Сайт имеет право отвергнуть попытку изменения токена (например, если такого токена в его базе не было или он их вообще их не сохраняет) параметром
CSI-Token-Action: aborted.
До тех пор, пока браузер не получит заголовок CSI-Token-Action, он в каждый запрос к сайту в заголовок CSI-Token будет добавлять ключ Changed-To.
Это
аналог «смены пароля» пользователя.
9 Как реализуется кросс-доменная авторизация?
Классическая кросс-доменная авторизация по технологии
SSO
имеет для пользователя много плюсов. Вам нет необходимости помнить кучу паролей от кучи сайтов. Нет необходимости в регистрации и заполнении муторных форм. Некоторые сервера авторизации спрашивают какие права предоставить сайту, запросившему SSO.
Но есть и недостатки.
Вы в зависимости от поставщика SSO.
Если не работает сервер SSO, на целевой сайт вы не попадете. Если вы теряете пароль или у вас угоняют вашу учётку – вы разом теряете доступ от всех сайтов.
Для веб-разработчиков всё чуть сложнее. С начала необходимо зарегистрировать свой сайт на сервере авторизации, получить ключи, научиться работать с протоколом (
SAMLOAuth
1-ый вариант решения: обновить allauth до версии 0.36.0
В allauth версии 0.36.0 этот параметр добавили, поэтому обновите allauth до указанной версии и всё должно заработать.
0 Алгоритм формирования ключа домена
Настоящий протокол определяет только 2 способа формирования ключей домена
В последнем случае ключ домена вычисляется как:
где
– 256-битный мастер-ключ, Domain – доменное имя, для которого делается ключ.
Здесь и далее
HMAC
на основе 256-битной реализации хеш-функции
Компрометация или добровольное разглашение ключа домена не приводит к компрометации исходного мастер-ключа.
Мастер-ключ обеспечивает механизм мобильности учётных данных пользователей.
Если ключ, созданный на базе «мастера», был скомпрометирован, либо был скомпрометирован токен, вычисленный от такого ключа (в результате взлома сайта), то ключ необходимо поменять. Поменять можно на случайный 256-битный ключ, либо сгенерировать от того же «мастера», с добавлением версии:
Здесь и далее символ
будет использоваться для операции конкатенации строк (массивов байт).
1 Алгоритм вычисления исходного токена
Идентификационный токен пользователя вычисляется при каждом запросе любого ресурса домена. Для вычисления токена запроса берутся следующие данные:
Эти данные конкатенируются и подвергаются хэшированию 256-битной SHA-2
на ключе K домена-инициатора запросаВалидный токен получается, когда Context не пуст. Для правильной идентификации на целевом сайте необходимо, чтобы выполнялось условие Sender = Recipient = Context.
Поле Context вкупе с Protection используется для защиты от
XSSCSRF
-атак, а также от трекинга пользователя.
Более подробные пояснения по правилам определения Sender / Recipient / Context будут даны ниже.
2 Алгоритм защиты токена при передаче
Исходный токен клиента передается крайне редко. Только при передаче незарегистрированного токена в момент создания сессии.
Токен считается незарегистрированным
, если он: создан на базе случайного (не зафиксированного) ключа; не был принят сервером после отправки ключа Change-To или Permanent. Подробнее см.
Браузер и сервер совместно вырабатывают пару случайных чисел, т.н. соль (Salt), при помощи которой хешируются младшие 128 бит токена. Оба обмениваются этими числами согласно протоколу. Подробнее см.
Таким образом, сервер сайта видит следующий токен:
где
– старшие 128 бит,
– младшие 128 бит исходного токена,
– конкатенация строк. При этом исходный токен
должен быть уже известен серверу.
В идеале CSI-Salt должен меняться при каждом запросе браузера к серверу. Однако это может быть затратным требованием с точки зрения вычислительных ресурсов. Кроме того, это может «убить» возможность отправки параллельных запросов на сервер.Поэтому допускается, в целях оптимизации расчетов, сохранение неизменным значения CSI-Salt в разных запросах, но не дольше одного сеанса.
Это может быть ограничение по времени (смена CSI-Salt каждые 5 минут), либо реакция на интенсивность запросов (смена CSI-Salt через каждые 100 запросов), либо после каждой серии запросов (в момент паузы клиент-сервер), либо смешанный вариант. Здесь решение оставляется за разработчиками браузеров.
Слишком долгое удержание неизменным CSI-Salt ослабляет защиту передаваемого токена, позволяя злоумышленнику, при перехвате токена, воспользоваться им, пока легальный пользователь не выполнил Logout, и выполнить неавторизованный запрос от имени жертвы.
3 Процедура обмена солью между браузером и сервером
2.3.1 Токен на базе случайного или незарегистрированного
тот домен, страницу которого мы загружаем (отображается в адресной строке браузера). Остальные домены будем называть
внешними
. Даже если это дочерние домены данного.
Назовем ресурс внешним, если он был загружен с внешнего домена. Назовем ресурс внутренним, если он был загружен с нашего домена. Ресурсом может быть скрипт, изображение, ajax-запрос и любой другой файл.
Скрипт считается внешним, если он был загружен с внешнего домена. Скрипт, размещенный в созданном теге <script>, созданный внешним скриптом, тоже будет считаться внешним. Скрипт, располагаемый в измененном теге <script>, объявляется внешним, если изменялся внешним скриптом, или внешний скрипт присутствовал в цепочке вызовов при изменении его содержимого. Даже если при этом данный <script> изначально был на странице или был создан внутренним скриптом.
Назовем теги LINK, SCRIPT, IMG, IFAME и другие, которые требуют от браузера догрузить какой-либо ресурс, как только будут встречены парсером DOM – ресурсными тегами.
Назовем теги FORM, A, META и другие, которые могут инициировать загрузку страницы при определенных условиях (submit, click, timeout) – инициирующими тегами.
Назовем тег статическим, если он изначально присутствовал на странице при первичной выдаче сервером. Назовем тег динамическим, если он был создан в процессе работы скриптов.
Тег FORM объявляется динамическим, даже если изменялся не только сам тег, но и значения всех полей INPUT, связанных с этой формой.
Назовем динамический тег собственным, если скрипт его создавший, принадлежит нашему домену, а в цепочке вызовов инструкции, породившей данный тег, не было функции, принадлежащих внешнему скрипту. В противном случае считаем такой динамический тег несобственным.
Загрузка страницы провоцируется инициирующими тегами. Инициирующий тег может быть приведен в действие непосредственно пользователем, либо активирован скриптом, через выполнение команды click (для ссылки), и submit (для формы) или через генерацию скриптом соответствующих событий onclick/onsubmit.
6 Подробнее о значениях таблиц определения Context
Рассмотрим подробнее, какие варианты открытия страниц (вкладок в браузере) у нас имеются, и какое значение Context будет при этом получаться.
P1 – пользователь на предыдущей странице щелкнул ссылку или нажал кнопку submit на форме. Стандартный обработчик браузера событий для ссылки/формы перенаправил пользователя на эту страницу. Нормальная ситуация. Безопасный переход между страницами домена или разных доменов.
7 Сценарии работы протокола
Приведем основные вероятные сценарии работы пользователя с сайтом, затрагивающие все возможные ситуации и этапы их выполнения (анонимный вход, «запомнить меня», «забыть меня», перейти на использование постоянного ключа, авторизация и выход, регистрация и двух-факторная аутентификация, экспорт/импорт ключа, замена ключа и т.п.)
Пример конфигурации доступа по токенам на базе файла .htaccess.
7.1 Алгоритм расчета сайтом возможных токенов пользователя по известному ключу
Если нам известен ключ K домена, мы легко можем рассчитать возможный «валидный» токен T пользователя, который придет с его запросами. Для этого необходимо, чтобы было выполнено условие: инициатор запросов, получатель запросов и контекст выполнения должен совпадать и быть равен домену. Иными словами, если у нас доменное имя vsphere.local, то:
При передаче, исходный токен будет дополнительно защищен. Младшие 128 бит токена будут хешированы солью, передаваемой в заголовке запроса CSI-Salt
*
. Таким образом, сайт увидит следующий токен:
Где
Hi
– старшие 128 бит,
Lo
– младшие 128 бит исходного токена.
Обычно, для закрытых консолей управления в корпоративной сети, веб-консоли не подгружают внешних скриптов, фреймов и т.п. Поэтому это условие будет в большинстве случае выполнено.
2-ой вариант решения: переопределить vk провайдер
Если по каким-то причинам не хотите обновлять allauth, то вы можете и другим способом решеть проблему, добавив свой кастомный VK провайдер. Для этого нужно скопировать провайдер vk из приложения allauth (находится в allauth/socialaccount/providers/vk/) куда-нибудь в своё приложение, например, spec/providers/vk.
Добавляем в файле spec/providers/vk/views.py параметр ‘v’: ‘5.101’, в словарь params в функции complete_login класса VKOAuth2Adapter. Полный листинг приведён ниже:
1 Защита ключевой информации от НСД
Предлагаемый протокол авторизации защищает пользователя от клавиатурных шпионов, крадущих ваши пароли, поскольку в предлагаемой схеме пароли не используются вообще.
А вот способы защиты ключей от компрометации необходимо рассмотреть подробнее.
Ключи могут быть скомпрометированы путем:
Если допустить, что ключевая информация сохраняется на смарт-карте (мы рассматривали данный вариант в разделе
), то задача защиты ключевой информации перекладывается на плечи чипа. Правда появляется уязвимость к клавиатурным шпионам, которые могут перехватить вводимый PIN-код; ну и неудобность в использовании.
Помимо смарт-карт для защиты от прямого доступа к ключевой информации можно использовать симметричное шифрование. Но вопрос: какой ключ взять для шифрования?
Если этот ключ генерировать на базе пароля пользователя, то во-первых, получаем уязвимость к подбору пароля «офлайн», во-вторых, собственно, от чего ушли, к тому и пришли: «опять какие-то пароли».
Более правильный вариант зашивать особым образом* такой ключ в сборку браузера (или одной из его специализированных библиотек). При каждом обновлении браузера меняется и ключ, и место его расположения в скомпилированном файле.
Также сами ключи доменов непосредственно должны храниться в отдельном файле, а не совместно с конфигурацией по их использованию (т.е. только ключи и ничего более). Тогда их расшифровка методом подбора ключа (из известных сборок) будет невозможна, ибо отличить правильно расшифрованный ключ от случайной последовательности байт – невозможно.
Можно применить комбинированный вариант: шифрование ключом от браузера шифрование паролем пользователя от учетной записи ОС (если это позволяет API ОС). Причем ключ всегда генерируется «на лету». Тогда офлайновый брутфорс станет ещё затратнее.
Кроме того, после смены пароля пользователя в ОС, ключ тоже изменится. И если не сделать предварительную расшифровку на старом ключе, то это защитит от ситуаций, когда администратор компьютера меняет вам пароль, чтобы получить доступ к вашей учетной записи и выполнять действия от вашего имени. Ситуации вида: уволился с работы.
Вы же предварительно сделаете резервную копию ключей (экспортируете ключи в файл). Если, конечно, уже не сделали этого ранее при распространении ключей на другие устройства.
2 О паролях в качестве ключей доменов
В одной из первоначальных версий протокола ключ домена мог формироваться на базе пароля пользователя. Алгоритм был хитрым, исключавшим повторение ключей у разных доменов для одного и того же пароля.
Это позиционировалось как удобный способ мобильности учетных записей. Ввел один пароль и не переживаешь ни о чём. Но потом оказалось следующее:
Если сайт знает свой токен, то сайт может восстановить «брутфорсом» пароль, который был положен в основу формирования ключа домена, формирующий этот токен. А если предположить, что этот пароль пользователь использовал ещё где-либо, то мы получим ключи доменов и от других сайтов пользователя.
Допустим (гипотетически), что вы используете сложный 8-ми символьный пароль, состоящий из символов латинского алфавита разного регистра, цифр и таких спец.символов: ~!@#$%^&. Общий алфавит составит: 26 26 10 8 = 70 символов. 8-символьный пароль на таком алфавите имеет ёмкость 708 вариантов.
Представим, что злоумышленник имеет специализированный кластер, способный вычислять наши токены из пароля со скоростью 1012 вариантов в секунду. Тогда для взлома ему потребуется 708 / 1012 = ~576 сек. Т.е. ваш пароль будет гарантировано подобран за ~10 минут. А в среднем такой системе будет достаточно потратить лишь 5 минут на подбор пароля от известного токена. 10-символьный пароль потребует уже в среднем 15 суток. Но повысив производительность системы в 10 раз, мы сократим это время до 1-2 суток.
А такая производительность теперь есть и легко доступна благодаря облачным сервисам, распределенным вычислениям и всего того наследия майнинговых фрем.
Такой пароль уязвим не только к брутфорсу, но и к клавиатурным шпионам.
Если два незнакомых друг другу пользователя придумают для одного и того же популярного сайта одинаковый пароль, то они получат одинаковый токен. Т.е. пароли могут вызвать конфликт токенов (несмотря на длину хеша и всю мощь SHA-2).
Ну и, наконец, создавая протокол, я хотел вообще уйти от паролей. А на самом деле лишь похитрее их спрятал.
3 Риски потери/компрометации ключей и их минимизация
А что если я потеряю мастер-ключ?
Такое может произойти, если вы поменяли пароль или переустановили ОС. Какие риски?
Ну вы не попадете на сайты, где были раньше. Потеряете историю покупок на интернет-магазинах, свои объявления на интернет-площадках, карму на форумах. Не беда.
Хотя, кто мешает сделать процедуру перерегистрации с новым токеном и подтверждением его через телефон, указанный в том же объявлении? Получается, что сайту необходимо делать форму перерегистрации токена (аналог «восстановления пароля»)? Где же обещанное отсутствие «всяких таких» форм?
На самом деле сайту, которому необходимо не просто идентифицировать посетителя, а ещё и знать кто это на самом деле, придется делать форму регистрации. Собственно, эта форма может использоваться для повторной регистрации. Вы указываете ровно те же данные, что и ранее (email, mobile).
Но всё-таки, лучше не терять мастер-ключ.
Как предотвратить потерю? Создавать резервную копию, защищать её паролем и хранить на отчуждаемых носителях. Так же, собственно, как это делается с ключами для bitcoin. В принципе, можно переводить мастер-ключи в печатный вид и сохранять на бумажке. Если на то пошло. А потом восстанавливать ручным вводом. Но это уже для совсем «параноиков», вроде меня. А что если у меня угонят мастер-ключ?
Это уже серьезно. Хотя описываемые здесь рекомендации по хранению мастер-ключа (не входят в протокол) защищают их от прямого НСД, клавиатурных шпионов и троянов, тем не менее, риск компрометации мастер-ключа сохраняется. К сожалению, идеальной защиты не существует. Ключ может быть угнан прямо из памяти браузера через уязвимость движка javascript. Как пример. Или вы теряете мобильник…
Так какие риски угона мастер-ключа?
Существенные для получения сведений о вас и даже для совершения действий от вашего имени. Получение возможности злоумышленнику авторизовываться под вами и в режиме чтения получать доступ к закрытой информации. Тихо и незаметно. Или разом выкачать все ваши приватные видео из одноклассников. Вам неприятно. Любители котиков ликуют.
Здесь необходимо быстро перерегистрироваться с новым ключом на важных сайтах. И, если случилось страшное, регистрация вашего нового токена в БД поставщика услуг официальным способом, – единственный правильный вариант. Способов регистрации можно придумать множество: от бумажной фиксации в официальном письме, до заявки через службу техподдержки сайта с подтверждением личности приемлемыми способами. Но это только для серьезных сайтов, вроде онлайн-банка.
Способы минимизации рисков. Использование индивидуальных ключей для доменов (но это понижает мобильность учёток). Двухфакторная аутентификация по независимым каналам. Показ сайтом IP-адресов и устройств, откуда было подключение в последний раз, чтобы вы хотя бы вовремя заметили компрометацию.
Сайт, которому вы доверяете, может беззастенчиво сливать о вас информацию другим сайтам. В интернете существуют сайты-коллекторы, которые агрегируют такую информацию и продают её желающим. Яндекс-метрика, гугл-аналитика – редкий сайт обходится без них.
Чтобы два разных сайта могли определить, что работают с одним и тем же клиентом, применяются две техники:
Выполнение одного сайта в контексте другого и взаимный обмен собственно сгенерированными идентификаторами пользователей (в качестве идентификатора может использоваться всё, что угодно из вашего профиля).
Формирование отпечатка браузера по единому алгоритму (формирование уникального набора атрибутов браузера) и косвенная идентификация клиента по этому отпечатку.
В схеме 2 есть небольшой недостаток:
идентифицируется не пользователь
, а браузер. Но зачастую браузер == клиент.
Кажется, токен лучшим образом подходит к использованию в схеме № 2. Ведь если пользователь разрешил «запомнить» себя двум сайтам (действующим в паре), наш постоянный токен может выступить в роли такого «отпечатка», только уже не браузера, а самого пользователя. Проблема для сайтов здесь в том, что они получат разные токены.
Но ведь сайты могут попробовать применить ещё и схему № 1. Тогда получится следующее.
Сайт 1 получит от браузера код H1, а сайт 2, выполняемый в контексте сайта 1 – код H2. Кажется, теперь сайты могут сформировать пару (H1, H2) и даже передать это некому сайту-агрегатору.Пусть есть ещё один сайт 3, который работает в паре с сайтом 2, пытаясь вас отследить.
Сайт 3 получит от браузера токен H3, а сайт 2, выполняемый в контексте сайта 3 – токен H2′ != H2 (см. как формируется токены). Как результат, объединение полученных данных невозможно, т.к. у них нет пересекающихся частей.
Но это не значит, что сайты не смогут использовать для слежки fingerprint браузера. Здесь утверждается только то, что схема генерации токенов сама по себе достаточно надежна и защищает от трекинга.
Вариант защиты: выходить из сайтов, с которыми вы закончили работу. Браузер может делать это автоматически при закрытии вкладки.
4 Трекинг с использованием схемы SSO
Два сайта S
1
и S
2
, которым пользователь доверяет и имеет для них ключи, решают применить технологию, аналогичную SSO, для трекинга пользователя. Но т.к. внедрить один сайт в другой нельзя (кто-то из них получит невалидный токен), открыть сайт партнера скриптом тоже нельзя (по этой же причине), то сайт S
1
решает применить хитрый прием.
На одной из страниц он размещает полупрозрачный тег A, перекрывающий всё окно. Ссылка ведет на сайт S2, а в адресе передается идентификатор пользователя (от S1) и токен H1. Пользователь не видит ссылку. Нажимая на любую область сайта S1, он инициирует открытие новой вкладки сайта S2.
В данный момент S2 не получит валидный токен. Не поможет ему и самоперезагрузка при помощи тега
5 Компрометация ключа для SSO
Пусть учетная запись пользователя на сервере аутентификации, поддерживающим SSO, компрометирована. Оценим возможные риски при нашей схеме аутентификации.
Токены для каждого сайта рассчитываются индивидуально на базе ключей доменов.
Компрометация одного ключа домена не ведет к автоматической компрометации всех остальных.
Большинство сайтов, где вы уже авторизовывались ранее при помощи SSO, наверняка сохранят в своей базе ваш токен с вашим профилем с сервера SSO. В нашей схеме, сайт просто будет подтягивать токен из БД и опознавать вас. Т.е. на таких сайтах сервер SSO уже не нужен – он выполнил свою функцию на этапе регистрации.
Иными словами вы не теряете автоматически разом все свои доступы. Злоумышленник при этом будет идентифицироваться на этих же сайтах как другой человек.
Не поможет злоумышленнику и попытка провести заново кросс-доменную аутентификацию: сайт должен блокировать попытки создания новой учетной записи со старым Id-пользователя SSO и новым токеном сайта. Либо попытки перезаписи токена пользователя для существующего Id в процессе SSO должны блокироваться.
Риск. Если сайт, не сохраняет в своей базе ваш токен и профиль, а целиком полагается на механизм SSO, тогда злоумышленнику достаточно провести кросс-доменную аутентификацию, чтобы авторизоваться под вашем именем.
Минимизация рисков при компрометации. Как ни странно, но это – сохранение сайтами токенов и профилей пользователей на своей стороне. Попытка злоумышленником провести кросс-доменную аутентификацию может вызвать конфликт между старым Id-пользователя и новым его токеном.
Максимальный риск: авторизация от вашего имени на других сайтах (где вы ещё не были). Доступ к данным вашего профиля. Совершение незаконных действий от вашего имени. А чтобы законный владелец не смог ничего вернуть, злоумышленник может поменять на сервере авторизации свой токен легальным способом. Этот риск, впрочем, совпадает с рисками, при использовании традиционных схем авторизации.
Способы защиты. Отказ от использования SSO (тем более, что предлагаемая схема и задумывалась как способ уйти от централизованных схем аутентификации). Использование нескольких SSO (не храните все яйца в одной корзине!).
Если SSO поддерживает двухфакторную аутентификацию с подтверждением личности по иным атрибутам (почта, телефон), то существует возможность восстановления контроля над учёткой сервера авторизации.
6 Компрометация токена при передаче
Понятно, что предложенный механизм хеширования токенов при передаче
не дает 100% гарантии
их защиты. Злоумышленник может перехватить трафик жертвы в момент передачи незащищенного токена (в момент первичной регистрации постоянного ключа), как пример. И потом использовать его.
7 Взлом сайта и компрометация токенов
Взломы сайтов происходят постоянно. Ломают даже крупные и хорошо защищенные сайты. Путей взлома много: от банальной инъекции, до инсайдерского «слива». Поэтому компрометация вашего токена на каком-либо сайте – событие весьма вероятное.
Но предлагаемый протокол, как раз-таки, делает событие взлома сайта наименее болезненным для вас.
Компрометация токена не ведет к компрометации ключа домена, на базе которого он был вычислен. Также это событие не ведет к компрометации других ваших токенов. А раз так, то доступы к другим сайтам остаются неприступными.
Особенно это приятно, когда к большинству сайтов ключи сделаны при помощи мастер-ключа: его восстановить реверс-инжинирингом невозможно.
Но при этом использовать ключ домена, чей токен был скомпрометировать, уже, по понятным причинам, нельзя. Придется менять ключ.
Ключ для домена, где произошла официальная утечка, можно сделать либо на базе случайного числа, либо на базе мастер-ключа, с добавлением номера версии:
Авторизация: вход после регистрации
Регистрацию проходят один раз. Потом для входа на какой-либо ресурс следует пользоваться кнопкой «Авторизация».
Вконтакте: регистрация и войти
Рис. 6. ВКонтакте: Регистрация и Войти.
Чтобы создать новую страничку ВКонтакте, следует ввести имя, фамилию, указать дату рождения и нажать на зеленую кнопку «Продолжить регистрацию».
Для входа на свою страничку, ранее уже зарегистрированную, следует ввести телефон или email, пароль и нажать «Войти».
Дополнительные материалы:
1. Зачем нужна регистрация на сайте?
2. Регистрация на сайте Одноклассники: пошаговые советы
3. Регистрация на сайтах в 2 клика через автозаполнение Яндекс браузера
4. Проблемы с входом в соцсети: причины и решения
Доверенный redirect uri
Во многих соц. сетях при добавлении приложения спрашивают про некий Доверенный redirect URI (или Действительные URL-адреса для перенаправления OAuth) например в ВК:
Доверенный redirect URI нужен для дополнительной защиты приложения от утечек токенов зарегистрировавшихся пользователей в следствие хакерских атак.
В django-allauthДоверенный redirect URI строится по следующему принципу:
Задача
Хотим небольшой модуль, который позволяет провести авторизацию красиво, универсально и максимально надежно, а использовать который очень просто.Стоит сказать, что данное решение является усовершенствованием и обобщением варианта, предложенного в этой статье.
Итак, используем python3.5, библиотеку для html запросов requests и getpass для скрытого ввода пароля.
Наша задача: несколько раз обратиться по верному адресу, каждый раз парсить <form>, отправлять ответ и наконец получить желанный access_token.
Настройка ссылки для входа
Первым делом сформируем ссылку используя которую пользователь нашего сайта сможет дать необходимые разрешения, на запрошенные нашим сайтом действия, например доступ к контактам.
Отправка токена с ключом change-to
Назовем старый токен T, новый – Т’.
ВАЖНО: в качестве нового токена T’ посылается реальное значение токена (в первый раз, для незарегистрированных), тогда как старый токен посылается хешированный (младшие 128 бит).
Отправка токена с ключом logout
Указывает на то, что текущий токен больше не будет использоваться браузером. Отправляется когда пользователь нажал «Выход» в браузере, или закрыл вкладку и настроена опция (автовыход при закрытии вкладки), или отказался от использования фиксированного ключа («забыть меня на этом сайте»).
Отправка токена с ключом permanent
Браузер фиксирует ключ клиента. Пользователь хочет, чтобы сайт запомнил клиента дольше, чем на одну сессию. Сохранять ли токен пользователя в своей базе – решение принимает сервер. Возвращаем клиенту CSI-Token-Action: success или CSI-Token-Action: abort.
Ошибка resp.json()[‘response’][0] keyerror: ‘response’ для vk провайдера
Данная ошибка возникает в версиях allauth ниже 0.36.0 из-за того, что ВКонтакте изменили api, сделав параметр v обязательным (v – версия api vk).
Перенос через физическое отчуждаемое устройство
Смарт-карты и usb-токены могут вполне подойти в качестве защищенного хранилища ключевой информации (ибо для этого и создавались). Двухфакторная аутентификация защищает ключи от НСД при непосредственном доступе к устройству.
Правда для смарт-карт требуются специальные считыватели (не говоря уже про драйвера), что ограничивает их применение только рабочими станциями, оборудованными такими считывателям.
С USB-токенами чуть проще. Требуются только драйвера. Вот только такой токен в телефон не воткнешь. И хотя для мобильных телефонов существуют токены, выполненные в виде SD-карт, не сказать, что данное решение добавляет к мобильности. Попробуй вытяни карту из мобильника, да вставь в другой. И речь не о том, что это невозможно. Речь о том, что это не удобно.
А если токен поломается? Тогда все ваши ключи уйдут к «Великому Ктулху».
Так что появится соблазн при такой схеме использовать несколько устройств-дубликатов. Но тогда ещё необходимо решить вопрос с синхронизацией ключей, если у вас несколько смарт-карт.
Да и, честно говоря, не защищены такие устройства от клавиатурных шпионов. Вот если бы пин-код вводился бы с самой карты/токена. Тогда другое дело. Но я таких в природе не видел.
Плюсы: можно использовать случайный 256-биные ключи; высокая безопасность за счёт использования двухфакторной аутентификации; высочайший уровень защиты от прямого НСД. Минусы: зависимость от устройств; требует финансовых затрат; низкая мобильность; необходимость резервирования карт и, как следствие, синхронизации данных между ними; уязвимость к клавиатурным шпионам сохраняется.
Получение данных из вконтакте
И так, пропишем скрипт получения данных от vk по только что присланному code.
Реализация
Начнем с создания класса. При инициализации будем требовать список “разрешений”, к которым приложение хочет получить доступ, id этого приложения и версию API VK. Плюсом добавим несколько необязательных параметров, значение каждого из которых прояснится далее.
Как было сказано в уже упомянутой статье, нам необходимо искусно ворочать cookie и redirect’ы. Все это за нас делает библиотека requests с объектом класса Session. Заведем и себе такой в поле self.session. Для парсинга html документа используется стандартный класс HTMLParser из модуля html.parser.
Для парсера тоже написан класс (FormParser), разбирать который большого смысла нет, так как он почти полностью повторяет таковой из упомянутой статьи. Существенное отличие лишь в том, что использованный здесь позволяет изящно отклонить авторизацию приложения на последнем шаге, если вы вдруг передумали.
РЖД является сокращением от «Российские Железные Дороги». Сайт РЖД предназначен для получения информации о поездах, расписании, наличии мест. Для приобретения билетов на поезд необходимо создать личный кабинет на сайте РЖД, он называется «Мои заказы».
Для создания личного кабинета РЖД, а также для входа в правом верхнем углу на сайте РЖД есть единая кнопка «Вход» (цифра 1 на рисунке 3). Кликнув по ней, появятся две вкладки «Вход» (3 на рис. 3) и «Регистрация» (2 на рис. 3).
Чтобы создать новый личный кабинет, следует нажать «Регистрация». В новом кабинете «Мои заказы» НЕ будет билетов, приобретенных ранее на сайте РЖД. После регистрации там можно будет только купить новый билет.
Для доступа к прежнему кабинету, надо использовать кнопку «Вход». Там можно найти билеты, приобретенные ранее на сайте РЖД, а также купить новые билеты.
Ростелеком личный кабинет: зарегистрироваться и войти
Рис. 4. Кнопки «Зарегистрироваться» и «Войти» в личный кабинет на сайте Ростелекома.
На сайте Ростелекома можно создать новый личный кабинет с помощью кнопки «Зарегистрироваться» (цифра 1 на рисунке 4). В личном кабинете можно проводить оплату, получать и тратить бонусы, писать запросы в техподдержку и т.д.
Синхронизация через онлайн-сервис
«Облачные технологии» сейчас пихаются куда только можно. Похоже они, вкупе с блокчейном, стали заменой «банано-технологиям». Естественно, возникает желание, использовать некую интернет-площадку для обмена ключевой информацией. Этакая смарт-карта «онлайн».
А что? Авторизуешься по нашей схеме анонимно на таком сайте; отправляешь туда свои ключи зашифрованные паролем; заходишь с другого устройства на этот же сайт с тем же ключом/паролем; получаешь от туда ключи; синхронизируешь изменения по дате правки. Аналогично менеджеру паролей, только это онлайн.
Вот только, никто не гарантирует, что онлайн-сервис не будет взломан или не станет сам сливать ваши, пусть и зашифрованные, ключи «куда надо». Кто будет за бесплатно реализовывать такой сервис. То-то и оно.
Хотя, конечно, пароль защищает ключи от прямого использования. Но устойчив ли ваш пароль к брут-форсу «офлайн»? Тот ещё вопрос.
Плюсы:высокая мобильность учетных данных; независимость от устройства и браузера; нужен всего один единственный пароль (хотя от пароля не ушли, но уже лучше). Недостатки:менее безопасно, чем хранение ключей на отчуждаемом носителе. Фактически безопасность ключей основана на стойкости пароля к подбору.
Можно, конечно, использовать для шифрования других ключей мастер-ключ. Тот самый, при помощи которого вычисляются другие ключи доменов. Как вариант.
Фейсбук: создать аккаунт и вход
Рис. 5. Фейсбук: Создать аккаунт и Вход.
Шаг 1 – установка python social auth django
Делается это одной командой в вашем виртуальном окружении через утилиту pip
pip install social-auth-app-django
В документации предлагается при конфигурировании два вариант ORM для работы системы аутентификации через социальные сети. Это классическая ОРМ Django и ОРМ MongoEngine, но так получилось, что требуемый для MongoEngine пакет устарел и немного несовместим с последними версиями Django, просто не работает, даже в документации разработчиков mongoengine висит призыв о помощи с поддержкой утилиты. Поэтому будем настраивать только для классической ОРМ.
Шаг 1. запрос на авторизацию приложения
Аккуратно составляем url запроса (про параметры можно прочитать здесь), отправляем запрос и парсим полученный html.
Шаг 10 – запрос разрешений на получение доступа к email
У меня на сайте используется своя система рассылки сообщений уведомлений по почте, поэтому мне важно иметь доступ к email пользователю, чтобы уведомлять его о новых событиях на ресурсе, поэтому добавим запрос на получение доступа к email.
SOCIAL_AUTH_VK_OAUTH2_SCOPE = ['email']
Для Django рекомендую VDS-хостинг
TIMEWEB
Шаг 2 – регистрация батарейки на вашем сайте
Прописываем приложение аутентификации в INSTALLED_APPS
INSTALLED_APPS = (
...
'social_django',
...
)
Шаг 2. авторизация пользователя
Реализованы методы _log_in() и _two_fact_auth() для [не]успешной авторизации пользователя в вк, если он не авторизован (а он точно не авторизован). Оба метода используют ранее определенные поля email, pswd, two_factor_auth и security_code.
Если какое-то из полей не было подано аргументом при инициализации объекта класса VKAuth, их попросят ввести в консоли, а случае неудачи попросят ввести заново. Двух-факторная авторизация опциональна и по умолчанию отключена, и наш модуль уведомляет пользователя о ее присутствии ошибкой.
Шаг 3 – миграция базы данных
Вам потребуется применить изменения в структуре базы данных, поскольку данная батарейка имеет свои таблицы для работы с авторизацией пользователей.
./manage.py migrate
Далее последуем ещё одной рекомендации по настройке базы данных, если Вы, как и я, используете PostgreSQL. А именно…
При использовании PostgreSQL рекомендуется использовать встроенное поле JSONB для хранения извлеченных дополнительных_данных. Чтобы включить его, задайте настройку:
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
Шаг 3. подтверждение permissions и получение access_token
Самое сложное позади. Теперь дело за малым. Используем наше усовершенствование парсера формы, чтоб найти в только что поступившем к нам html документе кнопку с надписью “Allow” и вытащить из нее url подтверждения авторизации. Рядом находится кнопка с отказом – сохраним и ее url.
Шаг 4 – настройка бекендов аутентификации
Также прописываем в settings.py
Шаг 6 – настройка ключей для вконтакте
Здесь дана настройка секретных ключей для ВКонтакте
Рис. 2. В Юмани можно создать новый кошелек или войти в прежний кошелек.
Юмани – это электронные деньги, которые ранее были Яндекс.Деньги. Потом сервис был приобретен Сбербанком и сменил название. Были Яндекс.Деньги, стали Юмани.
Кнопка «Создать кошелек» (цифра 1 на рисунке 2) означает появление нового кошелька, как правило, с нулевым балансом. Другая кнопка «Войти» (2 на рис. 3) позволяет войти в старый кошелек. Возможно, там уже есть рубли и накопленные баллы.
Яндекс почта: создать id и войти
Рис. 1. «Создать ID» и «Войти» в Яндес.Почте.
В Яндекс.Почте кнопка «Создать ID» (цифра 1 на рис. 1) служит для регистрации нового почтового адреса (email). ID (читается «ай-ди») — это часть английского слова «identifier», что можно перевести как «идентификатор».
5 Правила определения полей Sender и Recipient
Sender – это домен страницы/скрипта/стиля, от которых идет запрос. Страница запрашивает стили, картинки, скрипты. Скрипты запрашивают контент через ajax. Стили могут подгружать другие стили. Это инициаторы запроса.
Recipient – это домен, на который реально уходит запрос.
Чтобы не осталось вопросов, рассмотрим на конкретных примерах.
Пусть есть сайт site.net. На главной странице сайта находится:
Заключение
Несколько моих знакомых, которым я показал статью, задавали мне по сути один и тот же вопрос: «А в чем здесь главная фишка?»
Если смотреть с высока
И действительно, поверхностный обзор протокола оставляет о нем впечатление (особенно с точки зрения конечного пользователя), как об ещё одном (очередном?) парольном менеджере, встроенном в браузер.
Ну, если сравнивать с парольными менеджерами, то всё-таки разница есть. Не уверен, что существует единый менеджер, реализованный в виде плагина для всех браузеров, работающий на всех платформах и умеющий синхронизировать ваши пароли между устройствами. Да ещё и бесплатный и открытый (чтобы из исходников собрать, в случае чего). Да и не факт, что разработчик такого менеджера не решит сделать «тихий слив» ваших учёток под благим предлогом «онлайн-синхронизации».
Серверы кросс-доменной авторизации тоже решение «так себе». Те же яйца Тот же парольный менеджер, только сбоку «онлайн». Тут вы доверяете владельцу сервера, а не разработчику менеджера. Но сервер могут взломать (и не важно Google это, или Facebook – утечки происходят рано или поздно у всех). Сервер может быть недоступен (вдруг его DDOS-ят или там просто тех.работы – ЕСИА в пример) или заблокирован каким-либо органом. Да и вообще, такие серверы под маской SSO любят собирать о вас слишком много информации, и нередко становятся целью хакеров со всего мира. Вам это нужно?
К тому же, мне, например, не прельщает перспектива регистрироваться в хомячковых соц.сетях только затем, чтобы авторизоваться на очередной интернет-барахолке и разместить там объявление купи-продай. Тем более, что регистрация в таких соц.сетях, становится всё строже и строже. Раньше требовался лишь подтвержденный email, потом телефон. Сейчас в наглую требуют реальную фотографию. Не удивлюсь, если скоро от нас будут требовать сдать отпечатки пальцев и кровь на анализ. Вам точно это нужно?
Я хочу интернет-независимости. А вы? SSO – не делает на свободными.
Наконец, есть же во многих браузерах встроенная фишка «запомнить пароль». Правда эта фишка исчезает при первой же переустановке ОС. Да и с мобильностью тут неважно. Даже между браузерами в пределах одного устройства. Фактически проблема с хранением паролей и их синхронизацией отдана на откуп самому пользователю. Крутись как можешь, чувак.
Некоторые хитрые браузеры предлагают войти куда-то там в облако и хранить «безопасно» пароли там. Но мы уже знаем, чем пахнет такое «безопасное облако». К тому же ставят вас в зависимоть от конкретного браузера, что уже не хорошо.
Так всё-таки, неужели в предлагаемом протоколе нет ни какой особой фишки?