Недавно наша группа собирается интегрировать другую систему управления A с другой системой B. Чтобы сделать ее более удобной для пользователей и избежать повторных входов в систему в нескольких системах, мы надеемся добиться этого эффекта - пользователям нужно войти в систему только один раз. чтобы иметь возможность войти между этими двумя системами, работать в системе. Очевидно, что это эффект, достигаемый **Single Sign-On**, и это как раз подходящее время, чтобы откровенно изучить волну знаний по технологии единого входа.
Основное содержание этой статьи следующее:
- Введение в систему единого входа
- Сравнение нескольких реализаций SSO
- Единый вход в систему Spring Boot на основе JWT
Уведомление:Концепция SSO существует уже давно.В настоящее время различные платформы имеют очень зрелые реализации, такие какOpenSSO
,OpenAM
,Kerberos
,CAS
Подождите, конечно, во многих случаях зрелость означает сложность. В этой статье не обсуждается использование этих зрелых решений и не рассматривается использование SSO в приложениях CS.
Что такое система единого входа
Простой момент: после одного входа в систему вы можете получить доступ к другим доверенным платформам без входа в систему. Например, после того, как мы войдем в Taobao, а затем откроем домашнюю страницу Tmall, мы обнаружим, что уже вошли в систему. SSO — это популярное решение для корпоративной бизнес-интеграции.
Как внедрить систему единого входа
Все мы знаем, что текущий http-протокол не имеет состояния, то есть первый запрос и второй запрос полностью независимы и не имеют значения, но на самом деле наша бизнес-логика является состоянием, что вводит cookie-сессионный механизм для поддержания состояния. Сторона браузера хранит идентификатор сеанса, а фон хранит данные, связанные с идентификатором сеанса. Каждый раз, когда выполняется запрос в фоновом режиме, этот идентификатор сеанса может передаваться для поддержания состояния. Затем идет кука, браузер автоматически подставляет данные из куки в запрос при отправке запроса и отправляет на сервер без ручной настройки.
Затем мы можем рассмотреть, что является ядром реализации SSO? Ответ заключается в том, как позволить платформе A войти в систему, а другие платформы также могут получить информацию для входа в систему платформы A (sessionId в механизме сеанса cookie).
Вариант 1 Совместное использование файлов cookie
В системе, основанной на механизме сеанса cookie, после входа в систему будет возвращен идентификатор sessionId, который будет сохранен в файле cookie. Если мы можем позволить другой системе получить этот файл cookie, мы не сможем получить учетную информацию. без повторного входа в систему. Бывает, что cookie браузера может достичь этого эффекта (см.междоменное обучение в Интернете и использование файлов cookie).
cookie позволяет совместно использовать файлы cookie на разных портах одного и того же доменного имени (или родительского-дочернего доменного имени), что отличается от политики одного домена http (http-запросы считаются междоменными, если протокол, доменное имя и порт не идентичны). Поэтому необходимо только развернуть несколько страниц переднего плана приложения на одно и то же доменное имя (или доменное имя родитель-потомок), а затем совместно использовать сеанс для достижения единого входа. Архитектура выглядит следующим образом:
Очевидным ограничением приведенной выше схемы является то, что не только главная страница должна делиться файлом cookie, но и фон также должен делиться сеансом (вы можете использоватьjwt
убить сессию, но это создаст новые проблемы, которые не будут здесь подробно описываться) Это решение слишком простое и далее объясняться не будет.
Вариант 2 основан на реализации обратного вызова
Как вы можете видеть из вышеизложенного, для достижения единого входа вам нужно только поделиться учетными данными пользователя с каждой системой, чтобы фон знал, что он сейчас谁
в гости. Это может достичь эффекта регистрации одновременно и доступ к везде, что действительно очень удобно. В механизме сеанса SESSESTID совместно используется, а затем несколько фонов могут использовать тот же источник сеанса. Здесь мы используем новый метод токена на основе JWT для реализации, если вы не знаете JWT, вы можете прочитать это:генерация и проверка java-jwtКороче говоря, jwt может нести информацию, которую нельзя подделать (фальсификация не пройдет проверку), поэтому мы можем поместить неконфиденциальную информацию, такую как идентификатор пользователя, непосредственно в jwt, чтобы завершить фоновый сеанс. Затем все, что нам нужно сделать, это поделиться jwt на каждой странице платформы. Архитектура системы следующая:
В этой архитектуре нет необходимости в какой-либо связи между бизнес-системой A и бизнес-системой B. Обе они имеют дело только с платформой аутентификации SSO, поэтому их можно развертывать произвольно без ограничения одного и того же домена. Вы можете спросить, как поделиться учетными данными (то есть строкой jwt)? Здесь нам нужно использовать параметр url для выполнения операции show. Текст резюмируется следующим образом: jwt хранится в localStore на передней части платформы аутентификации (не обязательно localStore, cookie, sessionStore), а затем бизнес-платформа несет свой собственный адрес обратного вызова и переходит к передней стойке аутентификации. center, а затем на стойке регистрации центра аутентификации. Возьмите ujwt в качестве параметра URL-адреса и вернитесь к адресу обратного вызова, тем самым завершив совместное использование jwt.
Текст, скорее всего, будет непонятен. Вот дорожная карта всего процесса:
Я считаю, что с помощью приведенной выше блок-схемы вы сможете примерно понять, как совместно используется jwt. Если вы все еще этого не понимаете, продолжайте читать. Простая аутентификация SSO, реализованная Spring Boot, приведена ниже. Основных систем две: центр сертификации SSO, система A (система A работает на разных портах, это системы A, B, C, D).
Настоящий
Внедрение центра сертификации единого входа
Сначала создается инфраструктура загрузки Spring.Поскольку это простой проект, в дополнение к основным зависимостям Spring Boot Web требуются только следующие дополнительные зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>
Полный файл POM доступен на github.
Фоновая реализация
В фоновом режиме не так много вещей, только следующие 5 методов:
-
/login
: выпустить токен jwt после успешного входа в систему.
В демонстрации это просто простое сравнение имени пользователя и пароля. Если они одинаковы, логин считается успешным, и токен возвращается. -
/checkJwt
: проверить действительность jwt
Проверить, действителен ли входящий jwt-токен, и вернуть список недопустимых jwt -
/refreshjwt
: обновить jwt
Определите, скоро ли истечет срок действия jwt, и если он вот-вот истечет, сгенерируйте новый jwt для возврата -
/inValid
: сделать jwt недействительным
Как jwt терпит неудачу, всегда был неприятным вопросом, каждый со своими плюсами и минусами. В этом примере для каждого jwt генерируется случайный секретный ключ, а jwt--secret сохраняется в redis.Если вы хотите сделать jwt недействительным, вам нужно только удалить запись в redis (таким образом, в Секрет нельзя получить при расшифровке). Но это делает механизм аутентификации без сохранения состояния (запись соответствия между jwt и secret).
Подводя итог, можно сказать, что фон SSO в основном выполняет две функции: проверяет имя пользователя и пароль и возвращает jwt, а также проверяет, является ли jwt законным. Конкретный код см. в каталоге sso на github.
Интерфейсная реализация
Логика стойки регистрации более сложная, не так просто понять, не понимаю, сколько раз вышеуказанная блок-схема.
Снова вернемся к вопросу SSO: совместное использование статуса входа. Как поделиться статусом входа (вот строка jwt) на переднем плане? Из-за ограничений браузера нет прямого способа обмена данными, кроме файлов cookie. Поскольку прямого обмена нет, должен быть косвенный способ!
Этот методПерезвони. Когда внешний интерфейс системы A переходит к внешнему интерфейсу SSO, он передает текущий путь в качестве параметра URL-адреса внешнему интерфейсу sso. После того, как внешний интерфейс sso получает jwt, он переходит к URL-пути, переданному системой A, и принимает jwt в качестве параметра URL. Это завершает передачу jwt от sso к системе A.
Например: вы заказали еду на вынос, как вам ее подадут другие? Очевидно, вы оставите адрес и попросите кого-нибудь принести вашу еду по этому адресу, и вы сможете насладиться едой. Это очень знакомо с передачей jwt.
Система А сказала: мне нужен jwt, пришлите его на адрес http://localhost:8081/test1/.
SSO сказал: Хорошо, этот адрес законный и может быть отправлен на JWT, поэтому перейти к нему:http://localhost:8081/test1/?jwt=abcdefj.asdf.asdfasf
Система А сказала: Неплохо, очень ароматно.
Будьте осторожны здесьесть ямаТо есть: если другая вредоносная система C установит такой же формат и перескочит на SSO и захочет получить jwt, то ей этого явно давать не надо. Таким образом, при переходе назад вам нужно решить, является ли адрес обратного вызова законным, можете ли вы передать его jwt, вы можете запросить оценку из фона или вы можете напрямую написать юридический адрес на переднем плане sso. В демо нет такого процесса суждения.
Внедряйте бизнес-системы
Код бизнес-системы очень прост: он в основном использует перехватчик для перехвата HTTP-запроса, извлечения токена и проверки того, действителен ли токен для центра аутентификации sso, а затем эффективно выпускает его, в противном случае он возвращает ошибку передний конец. Это слишком просто, чтобы размещать код, просто зайдите на github, и вы все поймете.
Эффект
Многое из вышеперечисленного является принципами, на самом деле сложность заключается в принципиальной части, а реализация кода не так уж и сложна. Я не буду публиковать код здесь, если вам нужно перейти непосредственно на github, чтобы увидеть его.
Вот несколько визуализаций:
- Система А входит в систему в первый раз
Видно, что для первого входа в систему вам нужно перейти в центр аутентификации sso, чтобы ввести имя пользователя и пароль для проверки входа. Запрос интерфейса считается успешным после успешного возврата логина.
- Измените порт запуска до 8082 и перезапустите его как система B
Видно, что на этот раз логиниться не нужно.После прыжка в центр аутентификации вы сразу прыгнете обратно.Если убрать оповещение, то не сможете увидеть процесс прыжка.
Наконец, выход из любой системы приведет к выходу из системы всех систем.
Видно, что после того, как система A войдет в систему, системе B и системе C больше не нужно будет вводить имя пользователя и пароль для входа. Если скорость достаточно высокая, вы даже не заметите процесс переключения на SSO и последующего отскока назад.
Исходный код:github
Эта статья была первоначально опубликована на:Уууу, она этого заслуживает? top/blog/detail…
Скан-код связан с общедоступным номером микроканала: исследовательские заметки FleyX, чтобы узнать больше о галантерее