Ответ 1
Пользователь должен быть перенаправлен на сервер аутентификации и получить новый токен (JWT), специально предназначенный для example2.com. Так работает OpenID Connect и любой другой межсетевой федеративный протокол SSO.
В Интернете много информации об использовании JWT (Json Web Token
) для аутентификации. Но я до сих пор не нашел ясного объяснения того, что должно происходить при использовании токенов JWT для единого входа в среде с несколькими доменами.
Я работаю в компании, которая имеет множество сайтов на разных хостах. Используйте example1.com и example2.com. Нам нужно одно решение для входа в систему, что означает, что если пользователь аутентифицируется на example1.com, мы хотим, чтобы он также автоматически аутентифицировался на example2.com.
Используя поток OpenId Connect, я понимаю, что пользователь, который хочет аутентифицироваться на example1.com, сначала будет перенаправлен на сервер аутентификации (или OP
: "поставщик OpenId" ). Пользователь аутентифицируется на этом сервере, который затем перенаправляет его обратно на исходный сайт example1.com с подписанным токеном JWT. (Я понимаю, что есть другой поток, который возвращает промежуточный токен, который может быть обменен на настоящий токен JWT позже, но я не думаю, что это требуется для нас)...
Итак, теперь пользователь возвращается на example1.com и аутентифицируется! Он может делать запросы, передавая токен JWT в заголовке Authentication
, и сервер может проверить подписанный JWT и, следовательно, способен идентифицировать пользователя. Ницца!
Первый вопрос:
Как следует хранить токен JWT на клиенте? Существует также много информации об этом, и люди, похоже, согласны с тем, что использование Web Storage
- это путь, а не старый добрый cookies
. Мы хотим, чтобы JWT сохранялся между перезапусками браузера, поэтому используйте Local Storage
, а не Session Storage
...
Теперь пользователь может перезапустить свой браузер, и он все равно будет аутентифицироваться на example1.com, если токен JWT не истек!
Кроме того, если example1.com должен сделать запрос Ajax другому домену, я понимаю, что настройка CORS позволит это. Но наш основной вариант использования - это не междоменные запросы, у него есть одно решение для входа!
Поэтому главный вопрос:
Теперь, каков должен быть поток, если пользователь переходит к example2.com, и мы хотим, чтобы он был аутентифицирован, используя токен JWT, который у него уже есть? Local Storage
, похоже, не разрешает междоменный доступ, поэтому в этот момент браузер не может прочитать токен JWT, чтобы отправлять запросы example2.com!
Должно:
Мы не хотим ничего интересного, мы будем довольны главным образом используемым решением!
Пользователь должен быть перенаправлен на сервер аутентификации и получить новый токен (JWT), специально предназначенный для example2.com. Так работает OpenID Connect и любой другой межсетевой федеративный протокол SSO.
Перенаправление пользователя на центральную службу аутентификации, когда пользователь не регистрируется для запроса учетных данных и выпускает новый токен аутентификации, является распространенным сценарием в системах единого входа с использованием известных протоколов, таких как oauth2 или OpenIdConnect
Однако, когда эта схема используется среди кросс-доменов, главный недостаток заключается в том, что пользователь будет проходить аутентификацию каждый раз, когда он перейдет в другой домен из-за политики одного и того же происхождения: токен сеанса не может быть разделены между доменами, поэтому SSO будет рассматривать пользователя как не прошедший проверку подлинности.
example2.com
не может получить доступ к данным example1.com
, но существует возможность обмена данными между доменами с использованием браузера localStorage/cookies и iframe, указывающего на промежуточный домен sso.example.com
Чтобы выполнить аутентификацию пользователя в example1.com
, перенаправьте его на сервер аутентификации в sso.example.com
, выпустите JWT после аутентификации и сохраните его в localStorage этого домена. После этого перенаправить пользователя в исходный домен example1.com
Создайте iframe в example2.com
, указав на sso.example.com
. Iframe в sso.example.com читает токен JWT и отправляет сообщение на родительскую страницу
Родительская страница получает сообщение и получает прикрепленный токен, продолжающийся с потоком SSO
Нет проблем с политикой того же происхождения, поскольку sso.example.com
имеет доступ к ее localStorage, и связь между iframe и родительской страницей разрешена, если источник и назначение распознают друг друга (см. http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage)
Чтобы упростить разработку, мы недавно выпустили перекрестный домен SSO с JWT в https://github.com/Aralink/ssojwt
Этот метод отлично совместим с потоками SSO. Это всего лишь способ совместного использования токена аутентификации без перенаправления и избежания ненужных входов в систему при объединении доменов.
Не уверен, если это ответит на ваш вопрос, но если ваша главная цель - это единый вход, я думаю, что простой обратный прокси-сервер разрешит вашу проблема (по крайней мере, междоменное хранилище).
Итак, example1.com example2.com
станет чем-то вроде
example.com/example1
example.com/example2
(И с пользовательской стороны это обычно чище)
Если это не вариант, вам может потребоваться настроить так, чтобы, когда пользователь проходит аутентификацию в 1 домене, он использует AJAX/скрытые фреймы для создания аутентификации с другими доменами (отправка 1-минутного токена через URL-адрес если вам нужно).
и если это не вариант, вам может потребоваться использовать имя пользователя + контакт, поскольку браузеры становятся более строгими в отношении междоменного взаимодействия.