Глобальная авторизация в веб-системах
…или как реализовать простой Single Sign-on в веб-системах.
Ниже описан простейший протокол, который даёт возможность нам сказать внешней системе, кто к нам вошёл, так, что внешняя система знает, что это говорим ей именно мы, а мы знаем, что мы говорим это именно ей.
- (П) Пользователь.
- (C1) Система 1 — клиент глобальной авторизации. В неё пришёл пользователь без авторизации.
- (С2) Система 2 — сервер глобальной авторизации. В ней пользователь уже авторизован, скорее всего, через cookie.
шаг | кто | что делает | кому | возможные ошибки |
---|---|---|---|---|
(П) → | (переходит по ссылке) → | C1 с любыми параметрами. ⇒ C1 хочет перенять авторизацию у С2. |
||
1 | C1 → | (делает GET-запрос напрямую) → | С2 с параметрами ga_id=ID&ga_key=KEY ⇒ С2 запоминает соответствие ID и KEY. |
С2 не ответила или ответ не в формате JSON («по факту», а не по MIME-типу ответа):
С2 ответила хешем в формате JSON, в котором присутствует поле «error» с непустым значением EEE:
|
2 | C1 → | (перенаправление браузера пользователя) → | С2 с параметрами ga_id=ID&ga_url=URL&ga_check=CHECK и опционально параметром ga_message=TEXT.
⇒ С2 даётся возможность прочитать cookie пользователя и получить данные о нём. Если это необходимо, на этом же шаге С2 может запросить у пользователь подтверждение передачи его учётных данных внешней системе, и в случае отрицательного решения передать на следующем шаге NOLOGIN. |
URL, на который происходит перенаправление, недоступен пользователю.
В запросе не передан или передан некорректный параметр ga_url, и также отсутствует HTTP-заголовок Referer, по крайней мере такой, который можно распарсить.
|
3 | С2 → | (делает POST-запрос напрямую) → | C1 с параметрами ga_client=1&ga_id=ID&ga_key=KEY&ga_data=DATA&ga_nologin=NOLOGIN
⇒ С1 запоминает соответствие ID и переданных данных. |
ID неизвестен серверу.
CHECK=0 и авторизовать пользователя в С2 невозможно.
Пользователь не доверяет C1 и запретил С2 передавать ей свои авторизационные данные.
C1 не ответила или ответ не в формате JSON. MIME-тип, опять-таки, не проверяется.
C1 ответила хешем в формате JSON, в котором присутствует поле «error» с непустым значением EEE:
|
4 | С2 → | (перенаправление браузера пользователя) → | C1 с параметрами ga_client=1&ga_id=ID&ga_res=CODE
⇒ C1 может взять сохранённые в предыдущем пункте данные и на их основе авторизовать пользователя. |
ID неизвестен клиенту:
Самая противная ошибка — это Redirect-Loop — бесконечное перенаправление, которое можно спровоцировать, если при ошибке авторизации никак не сохранить факт ошибки в браузере пользователя (например, с помощью cookie) и вместо того, чтобы показать страницу с ошибкой, отправить пользователя обратно на шаг 2 (через шаг 1). |
Важный момент: после успешной обработки любого запроса глобальной авторизации (запроса с параметрами ga_id или ga_client и т. п.), пришедшего со стороны браузера пользователя, как клиентской, так и серверной стороной, должно осуществляться перенаправление (HTTP 302 Moved temporarily) на адрес, не содержащий в себе параметров ga_id и т. п., для исключения повторной отправки запроса пользователем при нажатии «Обновить страницу».
И ID и ключ являются «секретными», но ID знают и сервера, и пользователь (ID передаётся в браузер), а ключ — только сами сервера. За счёт этого достигается безопасность: пользователь не может сам передать произвольные данные авторизации на сервер, не зная ключа. Для дополнительной защиты всё это можно просто пустить через HTTPS (SSL). Понятно, что кэш, в котором сохраняются соответствия ID и ключа, не должен быть доступен для чтения внешнему пользователю, иначе вся защита накрывается медным тазом. Для усиления защиты опять-таки можно дополнительно создать список доверенных серверов и при приёме данных авторизации проверять IP.
Как уже было сказано выше, данные авторизации — произвольные в JSON-формате. Однако, удобно специфицировать его чуть точнее: хеш, в котором есть поля user_name (логин), user_email (адрес электронной почты) и необязательные поля user_url (URL «домашней страницы» пользователя) и user_real_name («настоящее имя» пользователя).
OpenID, на самом деле, работает похоже, но почему-то адски глючит и его страшно использовать на своих внутренних ресурсах. :)
В реализации протокола очень желательна обработка ошибок и их показ пользователю в удобном виде, чтобы не получалось, как в OpenID — «она утонула» © (то есть «произошла ошибка» без каких-либо деталей).
FoF_Sudo
FoF_Sudo — беспарольная авторизация типа «от системы к системе».
Идея такая: пусть есть некая система (например FoF — фидридер), в которой действует глобальная авторизация (в качестве сервера выступает другая система), и пусть эта система должна авторизоваться на доверенных серверах (в примере — FoF должен забирать защищённые RSS-ленты от имени разных пользователей). Но при этом (!) пароль пользователя хранить в открытом виде в базе FoF нельзя. Да если бы и было можно, в данных глобальной авторизации его просто нету. При этом нужно, чтобы при передаче такой вот беспарольной авторизации какой-то совершенно левый пользователь не смог сделать так же и зайти под произвольным пользователем.
Как это сделать? Ответ — одноразовые ключи на каждый запрос:
- FoF видит в урле рсс’ки &fof_sudo=(что_угодно). Что_угодно — совершенно что угодно, единственно, в случае FoF оно должно быть разное для разных пользователей, иначе FoF двух пользователей подпишет на один и тот же защищённый фид, а обновлять будет вообще как попало — то от имени одного, то от имени другого пользователя.
- FoF генерирует случайный ID, запоминает соответствие этому ID пользователя и добавляет в запрос кукис:
- Cookie: fof_sudo_id=ID
- Система, к которой произошло обращение, видит этот кукис (fof_sudo_id) и делает обратный запрос к fof: /fof-sudo.php?id=ID
- FoF отвечает данными пользователя, которые он помнит по этому ID, в формате JSON ({'user_name':'user@custis.ru'}) и забывает ID
- Внешняя система верит, что теперь надо авторизоваться под именем юзера user@custis.ru (и, например, отдаёт правильную RSS’ку)
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить