Прозрачный пользовательский сеанс на нескольких сайтах (единый вход + единый выход) - PullRequest
35 голосов
/ 25 июня 2009

У меня есть несколько сайтов в разных доменах: example.com, example.org, mail.example.com и passport.example.org. Все сайты имеют общий внешний вид и должен иметь одну и ту же базу пользователей.

И в таком крайнем случае я все еще хочу, чтобы все сайты прозрачно (в максимально возможной степени) делиться сессиями пользователей со следующими ключевыми свойствами:

  1. Единая регистрация . Когда пользователь регистрируется на passport.example.org и посещает любой другой сайт - он должен рассматриваться как залогиненный.

    Зарегистрированные пользователи получают приветствие «Hello, $username» в заголовке сайта и другие навигационное меню, список услуг, к которым они имеют доступ. Если он не вошел в систему, вместо приветствия есть ссылка «Войти в систему», указывающая на passport.example.org/signon.

    Список доверенных доменов известен, поэтому его довольно просто реализовать. с OpenID или с каким-то легковесным протоколом. Когда пользователь впервые нажимает сайт, я перенаправляю его на специальную конечную точку аутентификации на passport.example.org, который затем молча перенаправляет его обратно, с идентификационной информацией (или «не подписан») анонимная личность). Для большинства браузеров это полностью прозрачно. Очевидно, что я использую одноразовые значения для борьбы с циклами перенаправления.

  2. Единый выход . Когда пользователь нажимает «выйти» в заголовке любого сайта в следующий раз, когда он посещает какой-либо сайт, его следует рассматривать как «не входящий в систему».

    OpenID не был предназначен для этого. Моя текущая идея (у меня уже есть частично работающая реализация) заключается в отправке не идентификатора пользователя, а «глобального» токена сеанса и совместного использования таблица глобальных сессий (global_session_token ↔ отношение пользователя) в БД.

  3. Поддержка роботов и пользователей без файлов cookie . Сайты имеют общественные зоны, которые должны быть доступным для пользовательских агентов без поддержки файлов cookie.

    Из-за этого перенаправление, о котором я упоминал в (1), становится проблемой, потому что для при каждом запросе страницы я в конечном итоге выкидываю пользовательский агент в конечную точку аутентификации и обратно. Это не только запутает роботов, но и загрязнит мою сессионную базу данных сеансы смерти при рождении очень быстро. И я определенно не хочу показывать «эй, у вас не включены куки, уходите! », это было бы очень грубо и разочарование. Хотя мне требуется поддержка cookie для входа в систему, я хочу, чтобы пользователи могли свободно читать для чего предназначены сайты и т. д. - без ограничений.

    И я явно не хочу помещать идентификаторы сеансов в URL-адреса, за исключением некоторых прозрачных междоменные перенаправления, которые я упомянул. Я считаю, что делать это является проблемой безопасности и, как правило, плохая вещь.

    И здесь у меня почти нет идей.

Хорошо, я знаю, что это сложно, но Google фактически делает это как-то с (google.com, google. лоты рДВУ , gmail.com и т. Д.), Верно? Так что это должно быть возможно.

Буду признателен за идеи описания протокола (это было бы лучше) или за ссылки к системам (либо код для чтения, либо просто живые сайты для просмотра и изучения) уже успешно реализовать что-то вроде этого.

Подводя итог: Несколько доменов без общего корня, общая база пользователей, единый вход, единый выход, для анонимного просмотра не требуется куки.

Все сайты находятся в одной сети (но находятся на разных серверах) и частично использовать одну и ту же базу данных PostgreSQL (опираясь на разные схемы одной и той же базы данных). Большинство сайтов написаны на Python / Django, но некоторые из них используют PHP и Ruby on Rails. Хотя я думаю о чем-то независимом от фреймворка и языка, я благодарен за указание на любые реализации. Даже если я не смогу их использовать, если я пойму, как это делается, может быть, я смогу реализовать нечто подобное.

Ответы [ 7 ]

31 голосов
/ 29 июня 2009

Хорошо, позвольте мне объяснить немного позже. (Все URL являются вымышленными!) Как я уже сказал, посетитель переходит на http://www.yourwebpage.com и указывает, что хочет войти в систему. Он перенаправляется на http://your.loginpage.org? Return = http://www.yourwebpage.com/Authenticated, где ему придется укажите его имя пользователя и пароль.
Когда данные его учетной записи действительны, он вернется на страницу, указанную в URL-адресе для входа, но с дополнительным параметром, который будет использоваться в качестве идентификатора. Таким образом, он переходит к http://www.yourwebpage.com/Authenticated?ID=SharedSecret, где SharedSecret будет временным идентификатором, действительным в течение 30 секунд или менее.
Когда вызывается ваша страница аутентификации, она затем вызывает метод, который используется совместно yourwebpage.com и loginpage.org для поиска информации об учетной записи SharedSecret для получения более постоянного идентификатора. Этот постоянный идентификатор хранится в веб-сеансе yourwebpage.com и НИКОГДА не должен показываться пользователю.
Общий метод может быть чем угодно. Если оба сервера находятся на одном компьютере, они могут получить доступ к одной и той же базе данных. В противном случае они могут общаться с другим сервером через веб-сервисы. Это будет взаимодействие между серверами, поэтому не имеет значения, является ли пользователь роботом или не имеет поддержки cookie. Эта часть не будет замечена пользователем.
Единственное, с чем вам придется иметь дело, это сеанс для пользователя. Обычно пользователям отправляют идентификатор сеанса, который хранится в файле cookie, но он также может быть частью URL-адреса как часть запроса GET. Однако немного безопаснее иметь идентификатор сеанса внутри запроса POST, добавив скрытое поле ввода в форму.

К счастью, некоторые языки веб-разработки уже предоставляют поддержку сеансов, поэтому вам даже не нужно беспокоиться о поддержке сеансов и отправке идентификаторов сеансов. Техника интересная, хотя. И вы должны знать, что сессии всегда должны быть временными, так как существует риск того, что идентификаторы сессии будут взломаны.

Если вам приходится иметь дело с несколькими сайтами в разных доменах, то сначала вам нужно будет поработать над некоторыми межсерверными коммуникациями. Проще всего было бы позволить им совместно использовать одну и ту же базу данных, но лучше создать веб-сервис вокруг этой базы данных для дополнительной защиты. Убедитесь, что этот веб-сервис принимает запросы только от ваших собственных доменов, просто чтобы добавить еще немного защиты.
Когда у вас есть соединения между серверами, пользователь сможет переключаться между вашими доменами, и пока вы передаете идентификатор сеанса в новый домен, пользователь будет входить в систему. Если пользователь использует куки, не очень вероятно, что сеанс будет потерян, что потребует повторного входа в систему. Без файлов cookie есть вероятность, что пользователю придется снова войти в систему, чтобы получить новый файл cookie, если идентификатор сеанса теряется между страницами просмотра. (Например, посетитель посещает Google, а затем возвращается на ваш сайт. С помощью cookie-файла сеанс может быть прочитан из cookie-файла. Без cookie-файла сеанс теряется, поскольку Google не передает идентификатор сеанса вперед. br />
Помните, что передача идентификаторов сеансов между разными доменами представляет собой угрозу безопасности. Идентификатор сеанса может быть взломан, что позволяет кому-то другому выдавать себя за вашего посетителя. Поэтому идентификаторы сеансов должны быть кратковременными и запутанными. Но даже если хакер получит доступ к идентификатору сеанса, у него все равно не будет полного доступа к самой учетной записи. Он не сможет перехватить связь между серверами, поэтому он не сможет получить доступ к базе данных с вашей информацией о пользователе, если только он не перейдет на страницу входа напрямую.

5 голосов
/ 25 июня 2009

AFAIK, Google просто использует куки для домена "Google.com". Но Google также использует OpenID, который учитывает общий механизм входа в систему. По сути, это работает, перенаправляя вас на специальную страницу входа. Эта страница входа в систему обнаружит, вошли вы в систему или нет, и если вы не вошли в систему, она попросит вас войти в систему. В противном случае она просто перенаправит вас прямо на следующую страницу.

Итак, в вашем случае пользователь откроет somepage.example.com, и у сеанса для этого приложения нет идентификатора входа. Таким образом, он будет перенаправлять пользователя на logon.example.biz, где пользователь будет входить в систему. За этой страницей также будет сеанс, и этот сеанс будет сообщать, что пользователь уже вошел в систему. (Или нет, в этом случае пользователь должен сначала войдите в систему.) Затем он перенаправляет пользователя somepage.example.com?sessionid=something, где этот sessionid будет храниться в сеансе somepage.example.com. Затем этот сеанс также будет знать, что пользователь вошел в систему, и для пользователя он будет казаться почти прозрачным.

На самом деле, пользователь перенаправляется дважды.

1 голос
/ 09 июля 2009

Для этого решения не нужен паспортный сервер.

* 1003 для входа в аккаунт *

  1. Логин
  2. Создание токена с зашифрованным идентификатором сеанса и другой информацией
  3. Показать img с токеном со всех ваших доменов для установки файлов cookie на его.

Авторизация по cookie

  1. У вас уже есть файлы cookie на всех доменах.

Выйти

  1. Очистить печенье
  2. Уничтожить сессию
  3. Очистить связь идентификатора пользователя с последним идентификатором сеанса в БД (я думаю, вы сохраняете идентификатор сеанса в пользовательской таблице для увеличения сеанса с помощью cookie)

Я не могу попробовать это решение. Но теперь у меня та же проблема, что и у вас (SSO), и я попробую это завтра.

1 голос
/ 26 июня 2009

Если все ваши приложения находятся в одном домене, то это не так уж сложно, поскольку вы можете использовать куки-файл уровня домена для управления сеансом управления. (Управление сеансами без файлов cookie сложно, но можно сделать, но сложно.)

Однако вы указали несколько сайтов в домене example.com, а некоторые - в домене example.org.

Немного поиграв с моим Google gigh-in и другими их сайтами orkut.com, похоже, что когда вы попадаете на страницу, требующую учетных данных, она перенаправляет вас на общий сайт для входа в учетную запись, который затем перенаправляет вас обратно. на исходный сайт, предположительно передавая какой-то токен сеанса в URL. Исходя из этого, предположительно, серверы orkut.com напрямую связываются с серверами google.com, чтобы проверить токен и получить любую другую информацию о пользователе.

Дополнительная информация о cookie-файлах на уровне домена при запросе

Если у вас есть два сайта, скажем, foo.example.com и bar.example.com,, вы можете установить cookie, специфичные для хоста, но вы также можете установить cookie для домена, который будет виден всем хостам в домене.

Таким образом, foo.example.com может установить cookie для foo.example.com специально, и он будет виден только сам по себе, но он также может установить cookie для домена example.com,, и когда пользователь перейдет на bar.example.com, они также увидит этот второй файл cookie.

Однако, если у вас также есть сайт, snafu.example.org, он не сможет увидеть этот файл cookie уровня домена, который установлен foo, поскольку example.org и example.com - это два совершенно разных домена.

Вы можете использовать куки на уровне домена для хранения информации о сеансе между сайтами в одном домене.

Способ настройки файлов cookie домена зависит от среды разработки (извините, у меня нет опыта работы с rails).

1 голос
/ 25 июня 2009

Вы используете ASP.NET? Если это так, возможно, вы захотите взглянуть на свойство enableCrossAppRedirects .

0 голосов
/ 11 марта 2010

Плагин для междоменных доменов, способный сделать это, был бы великолепен.

Я бы хотел сделать это, единственный способ, которым я мог придумать, - заставить пользователя загрузить панель инструментов или какое-нибудь маленькое приложение, которое бы автоматически обрабатывало вход в систему.

Мне бы хотелось узнать другой путь, потому что это дует

0 голосов
/ 20 сентября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...