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

112

В Интернете есть много информации об использовании 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 !

Должен :

  • Пользователь снова будет перенаправлен на сервер аутентификации ? Когда пользователь прошел аутентификацию для example1.com , сервер аутентификации мог установить cookie для пользователя, чтобы этот новый запрос аутентификации для example2.com мог использовать этот cookie, чтобы видеть, что пользователь уже аутентифицирован, и немедленно перенаправляет его обратно на example2.com с тем же токеном JWT?
  • Или может браузер на example2.com получить доступ к токену JWT без повторного обращения к серверу аутентификации ? Я вижу, что существуют решения для перекрестного хранения , но широко ли они используются? Являются ли они предлагаемым решением для среды междоменного единого входа?

Мы не хотим ничего необычного, мы были бы довольны наиболее часто используемым решением!

электротипия
источник

Ответы:

28

Пользователь должен быть снова перенаправлен на сервер аутентификации и получить новый токен (JWT), специально предназначенный для example2.com. Так работает OpenID Connect и любой другой протокол междоменной федеративной системы единого входа.

Ганс З.
источник
15
Но без того, чтобы пользователю приходилось повторно отправлять учетные данные для аутентификации (например, имя пользователя / пароль), поскольку это SSO, верно? Итак, как это делается? Следует ли серверу аутентификации установить стандартный файл cookie для пользователя в первый раз, чтобы он мог автоматически аутентифицировать его, когда этот пользователь возвращается из нового домена?
electrotype
7
Но что, если пользователь настроил браузер на блокировку всех файлов cookie?
Christiaan Westerbeek
1
Я предполагаю, что о
файлах
единый вход в систему не обязательно означает, что у пользователя есть текущий сеанс, отслеживаемый файлом cookie: его определяющая характеристика заключается в том, что один и тот же поставщик удостоверений повторно использует одни и те же учетные данные для получения доступа к различным сторонним приложениям, т.е. cookie не требуется, просто повторное использование тех же кредитов
Hans Z.
35

Перенаправление пользователя в центральную службу аутентификации, когда пользователь не вошел в систему для запроса учетных данных и выдачи нового токена аутентификации, является распространенным сценарием в системах единого входа, использующих известные протоколы, такие как oauth2 или OpenId Connect.

Однако, когда эта схема используется в разных доменах, основным недостатком является то, что пользователь будет перенаправлен и аутентифицирован каждый раз, когда он переходит в другой домен из-за политики одного и того же происхождения : токен доступа не может совместно использоваться между доменами ( example2.comневозможно получить доступ к данным of example1.com), поэтому целевой домен будет рассматривать пользователя как не прошедшего аутентификацию, перенаправляя его в центральную службу единого входа.

Чтобы предотвратить повторный запрос учетных данных службой аутентификации, обычно используется файл cookie сеанса (а не токен доступа), но существует технология для обмена данными между доменами с использованием localStorage / cookie браузера и iframe, указывающего на промежуточный домен. sso.example.com

  1. Чтобы аутентифицировать пользователя example1.com, перенаправьте его на сервер аутентификации в sso.example.com, выдайте JWT после аутентификации и сохраните его в localStorage этого домена. После этого перенаправьте пользователя на исходный домен example1.com

  2. Создайте iframe, example2.comуказывающий на sso.example.com. Iframe в sso.example.com считывает токен JWT и отправляет сообщение на родительскую страницу.

  3. Родительская страница получает сообщение и получает прикрепленный токен, продолжая поток единого входа.

Нет проблем с политикой одинакового происхождения, потому что sso.example.comимеет доступ к своему localStorage, а связь между iframe и родительской страницей разрешена, если исходный и целевой домены распознают друг друга (см. Http://blog.teamtreehouse.com/cross-domain- сообщение-с-сообщением )

Чтобы упростить разработку, мы недавно выпустили междоменный SSO с JWT по адресу https://github.com/Aralink/ssojwt.

Этот метод полностью совместим с потоками SSO. Это просто способ поделиться токеном аутентификации без перенаправления и избежать ненужных входов в систему, когда домены объединены.

Pedrofb
источник
3
Помимо этого решения, не соответствующего стандарту, обычно в междоменном едином входе один пересекает административные границы, и в этом случае использование одного и того же JWT для обоих доменов открывает возможность для владельца приложения в одном домене выдавать себя за пользователя в другом. domain
Hans Z.
6
Спасибо @HansZ. Мы фактически реализовали это решение, чтобы иметь единое администрирование нескольких доменов с десятками приложений и одними и теми же пользователями. Операция аналогична системе Google (условно говоря)
pedrofb
2

Не уверен, что это отвечает на ваш вопрос, но если ваша основная цель - единый вход, я думаю, что простой обратный прокси-сервер решит вашу проблему (по крайней мере, междоменное хранилище).

Итак, example1.com example2.com

станет чем-то вроде

example.com/example1

example.com/example2

(А со стороны пользователя это обычно чище)

Если это не вариант, вам, возможно, придется настроить так, чтобы, когда пользователь аутентифицируется в 1 домене, он использовал AJAX / скрытые фреймы для создания аутентификации и с другими доменами (отправляя 1 токен времени через URL-адрес, если необходимо ).

и если ЭТО НЕ вариант, вам, возможно, придется прибегнуть к использованию имени пользователя + пин-кода, поскольку браузеры ужесточаются в отношении междоменного взаимодействия.

Tezra
источник