Автор: Лин Чэнъи
Ссылка на сайт:
http://www.cnblogs.com/ywlaker/p/6113927.html
«Дорога архитектора Явы» поставлена хореография
1. Единый механизм входа в систему
1. HTTP-протокол без сохранения состояния
Веб-приложение использует архитектуру браузер/сервер с http в качестве протокола связи. HTTP — это протокол без сохранения состояния. Каждый запрос браузера будет обрабатываться сервером независимо и не будет связан с предыдущими или последующими запросами. Этот процесс показан на следующем рисунке. Между тремя парами запрос/ответ нет связи.
Но это также означает, что любой пользователь может получить доступ к ресурсам сервера через браузер.Если вы хотите защитить некоторые ресурсы сервера, вы должны ограничить запросы браузера, чтобы ограничить запросы браузера, вы должны идентифицировать запросы браузера, отвечать на законные запросы и игнорировать Незаконный запрос, чтобы идентифицировать запрос браузера, необходимо знать статус запроса браузера. Поскольку протокол http не имеет состояния, пусть сервер и браузер поддерживают состояние вместе! Это механизм сеанса
2. Механизм сеанса
Когда браузер запрашивает сервер в первый раз, сервер создает сеанс и отправляет идентификатор сеанса браузеру как часть ответа.Браузер сохраняет идентификатор сеанса и передает идентификатор сеанса в последующих втором и третьем запросах. сервер узнает, является ли это тем же пользователем, получив идентификатор сеанса в запросе.Этот процесс показан на следующем рисунке.Последующие запросы связаны с первым запросом.
Сервер сохраняет объект сеанса в памяти, как браузер сохраняет идентификатор сеанса? Вы можете подумать о двух способах
-
параметры запроса
-
cookie
Принимая идентификатор сеанса в качестве параметра каждого запроса, сервер может естественным образом анализировать параметр, чтобы получить идентификатор сеанса при получении запроса, а затем судить, из того же ли он сеанса.Очевидно, что этот метод не является надежным. Затем браузер сам поддерживает этот идентификатор сеанса.Браузер автоматически отправляет идентификатор сеанса каждый раз, когда отправляется http-запрос, и для этого как раз используется механизм cookie. Файл cookie — это механизм, используемый браузерами для хранения небольшого количества данных. Данные хранятся в форме «ключ/значение», и браузер автоматически прикрепляет информацию о файлах cookie при отправке http-запросов.
Конечно, механизм сеанса tomcat также реализует файлы cookie. При доступе к серверу tomcat браузер может видеть файл cookie с именем «JSESSIONID», который является идентификатором сеанса, поддерживаемым механизмом сеанса tomcat. Процесс ответа на запрос с использованием файлов cookie выглядит следующим образом.
3. Статус входа
Благодаря механизму сеанса состояние входа в систему легко понять. Мы предполагаем, что при первом запросе браузера к серверу ему необходимо ввести имя пользователя и пароль для подтверждения личности. Сервер получает имя пользователя и пароль и сравнивает их. к базе данных. Пользователь является законным пользователем, и сеанс должен быть помечен как «авторизованный» или «зарегистрированный» и т. д. Поскольку это состояние сеанса, оно должно быть сохранено в объекте сеанса. статус входа в объект сеанса следующим образом
HttpSession session = request.getSession();session.setAttribute("isLogin", true);
скопировать код
Когда пользователь снова получает доступ, tomcat проверяет статус входа в объект сеанса.
HttpSession session = request.getSession();session.getAttribute("isLogin");
скопировать код
Модель сервера запросов браузера, которая реализует состояние входа в систему, описана на следующем рисунке.
Статус входа в объект сеанса проверяется каждый раз, когда запрашивается защищенный ресурс, и только сеанс с isLogin=true может получить доступ, поэтому механизм входа реализован.
Сложность нескольких систем
Веб-система уже давно превратилась из одной системы в прошлом в группу приложений, состоящую из нескольких систем.Сталкиваясь с таким количеством систем, должны ли пользователи входить в систему одну за другой, а затем выходить из системы один за другим? как описано ниже
Веб-система превратилась из одной системы в группу приложений, состоящую из нескольких систем, и сложность должна нести система, а не пользователь. Независимо от того, насколько сложна веб-система, она представляет собой единое целое для пользователей, то есть пользователи, получающие доступ ко всей группе приложений веб-системы, аналогичны доступу к одной системе, и достаточно один раз войти/выйти из системы.
Хотя решение для входа в одну систему идеально, оно больше не подходит для групп приложений, состоящих из нескольких систем.Почему?
Основой единого решения для входа в систему является файл cookie, который содержит идентификатор сеанса для поддержания состояния сеанса между браузером и сервером. Но файлы cookie имеют ограничения. Это ограничение — домен файла cookie (обычно соответствующий доменному имени веб-сайта). Когда браузер отправляет HTTP-запрос, он автоматически передает файл cookie, соответствующий домену, а не все файлы cookie.
В таком случае, почему бы не объединить доменные имена всех подсистем в группе веб-приложений под одним доменным именем верхнего уровня, например «*.baidu.com», а затем установить для их домена cookie значение «baidu.com». теоретический подход Да, даже в первые дни многие мультисистемные входы использовали этот метод совместного использования файлов cookie с одним и тем же доменным именем.
Однако то, что работает, не значит хорошо, и существует множество ограничений на способ обмена файлами cookie. Во-первых, доменное имя группы приложений должно быть унифицировано, во-вторых, технология, используемая каждой системой группы приложений (по крайней мере, веб-сервером), должна быть одинаковой, иначе значение ключа файла cookie (JSESSIONID для tomcat) равно другой, и сеанс не может быть сохранен.Платформа языковой технологии входит в систему, например, между системами java, php и .net, в-третьих, сам файл cookie не является безопасным.
Поэтому нам нужен новый метод входа в систему для входа в группу приложений с несколькими системами, который является единым входом.
3. Единый вход
Что такое единый вход? Полное название единого входа — Single Sign On (далее — SSO).
1. Войти
По сравнению с односистемным входом, SSO требует независимого центра аутентификации. Только центр аутентификации может принимать информацию о безопасности, такую как имя пользователя и пароль. Другие системы не предоставляют вход для входа и принимают только косвенную авторизацию из центра аутентификации. Косвенная авторизация достигается с помощью токенов. Центр аутентификации sso без проблем проверяет имя пользователя и пароль пользователя, создает токен авторизации. В процессе следующего перехода токен авторизации отправляется в качестве параметра каждой подсистеме, и подсистема получает токен. , то есть авторизованный, вы можете использовать его для создания локального сеанса, а метод входа в локальный сеанс такой же, как и в одиночной системе. Этот процесс, являющийся принципом единого входа, показан на следующем рисунке.
Ниже приводится краткое описание приведенного выше рисунка.
-
Пользователь обращается к защищенным ресурсам системы 1, а система 1 обнаруживает, что пользователь не вошел в систему, переходит к центру аутентификации sso и использует собственный адрес в качестве параметра
-
Центр аутентификации sso обнаруживает, что пользователь не вошел в систему, и направляет пользователя на страницу входа.
-
Пользователь вводит имя пользователя и пароль для подачи заявки на вход
-
Центр аутентификации sso проверяет информацию о пользователе, создает сеанс между пользователем и центром аутентификации sso, называемый глобальным сеансом, и одновременно создает токен авторизации.
-
Центр аутентификации sso отправляет токен на начальный адрес запроса (система 1).
-
Система 1 получает токен и обращается в центр аутентификации sso, чтобы проверить, действителен ли токен.
-
Центр аутентификации SSO проверяет токен, возвращает действительный и регистрирует систему 1.
-
Система 1 использует этот токен для создания сеанса с пользователем, называемого частичным сеансом, возвращая защищенный ресурс.
-
Пользователь получает доступ к защищенным ресурсам Системы 2
-
Система 2 обнаруживает, что пользователь не вошел в систему, переходит к центру аутентификации sso и использует собственный адрес в качестве параметра.
-
Центр аутентификации sso обнаруживает, что пользователь вошел в систему, возвращается к адресу системы 2 и прикрепляет токен.
-
Система 2 получает токен и обращается в центр аутентификации sso, чтобы проверить, действителен ли токен.
-
Центр аутентификации sso проверяет токен, возвращает действительный и регистрирует систему 2.
-
Система 2 использует токен для создания частичного сеанса с пользователем, возвращая защищенный ресурс.
После успешного входа пользователя в систему будет установлен сеанс с центром аутентификации SSO и каждой подсистемой. Сеанс, установленный между пользователем и центром аутентификации SSO, называется глобальным сеансом, а сеанс, установленный пользователем и каждой подсистемой, называется локальный сеанс.После того, как локальный сеанс установлен, пользователь получает доступ к защищенным ресурсам подсистемы, которые больше не будут проходить через центр аутентификации sso, а глобальный сеанс и локальный сеанс имеют следующие ограничения
-
Локальный сеанс существует, глобальный сеанс должен существовать
-
Глобальная сессия существует, но локальная сессия не обязательно существует
-
Глобальная сессия уничтожена, локальная сессия должна быть уничтожена
Вы можете углубить свое понимание единого входа через процесс входа в систему блога сада, Baidu, csdn, Taobao и других веб-сайтов, обратите внимание на URL-адрес перехода и параметры в процессе входа.
2. Отмена
Единый вход естественно также требует единого выхода.Если вы выйдете из подсистемы, сеансы всех подсистем будут уничтожены.Следующий рисунок используется для иллюстрации
Центр аутентификации sso отслеживает состояние глобального сеанса. После уничтожения глобального сеанса прослушиватель уведомит все системы регистрации о необходимости выполнения операции выхода из системы.
Ниже приводится краткое описание приведенного выше рисунка.
-
Пользователь инициирует запрос на выход из системы 1.
-
Система 1 получает токен в соответствии с идентификатором сеанса, установленным пользователем и системой 1, и инициирует запрос на выход из системы в центр аутентификации sso.
-
Центр аутентификации sso проверяет допустимость токена, уничтожает глобальный сеанс и удаляет все системные адреса, зарегистрированные с этим токеном.
-
Центр сертификации SSO инициирует запрос на выход из системы во все системы регистрации.
-
Каждая система регистрации получает запрос на выход из центра аутентификации sso и уничтожает локальную сессию.
-
Центр аутентификации SSO направляет пользователя на страницу входа.
4. Схема развертывания
Единый вход включает центр аутентификации SSO и общедоступные подсистемы. Подсистема и центр аутентификации SSO должны обмениваться токенами, проверять токены и инициировать запросы на выход. Поэтому подсистема должна интегрировать клиент SSO и центр аутентификации SSO. это sso. На стороне сервера весь процесс единого входа представляет собой процесс связи между клиентом sso и сервером, который описан на следующем рисунке.
Центр аутентификации sso может взаимодействовать с клиентом sso множеством способов.В качестве примера мы возьмем простой и удобный в использовании httpClient, веб-сервис, rpc и restful API.
5. Реализация
Просто краткое введение в процесс реализации на основе java, без предоставления полного исходного кода.Если вы понимаете принцип, я думаю, вы можете реализовать его самостоятельно. Sso использует архитектуру клиент/сервер. Давайте сначала рассмотрим функции, которые должны быть реализованы с помощью sso-client и sso-server (ниже: центр аутентификации sso = sso-server).
sso-клиент
-
Подсистема перехвата не регистрирует запросы пользователей и переходит к центру аутентификации sso.
-
Получите и сохраните токен, отправленный центром аутентификации sso.
-
Свяжитесь с sso-сервером, чтобы проверить действительность токена
-
Создать локальный сеанс
-
Перехват запроса пользователя на выход из системы и отправка запроса на выход в центр аутентификации sso
-
Получите запрос на выход, отправленный центром аутентификации sso, и уничтожьте локальный сеанс.
sso-сервер
-
Проверьте данные для входа пользователя
-
Создать глобальную сессию
-
Создайте токен авторизации
-
Свяжитесь с sso-client для отправки токена
-
Проверьте действительность токена sso-client
-
Регистрация системы
-
Получить запрос на выход из системы sso-client, выйти из всех сеансов
Далее реализуем sso пошагово по принципу!
1. sso-client перехватывает запросы без входа
Java перехватывает запросы тремя способами: сервлет, фильтр и прослушиватель Мы используем фильтр. Создайте новый класс LoginFilter.java в sso-client и реализуйте интерфейс Filter, а также добавьте перехват незарегистрированных пользователей в метод doFilter().
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); if (session.getAttribute("isLogin")) { chain.doFilter(request, response); return; } //跳转至sso认证中心 res.sendRedirect("sso-server-url-with-system-url");}
скопировать код
2. sso-сервер перехватывает запросы без входа в систему
Перехватывать запрос без входа, который переходит от sso-client к центру аутентификации sso, и переходить на страницу входа.Этот процесс точно такой же, как и для sso-client.
3. sso-server проверяет данные для входа пользователя
Пользователь вводит имя пользователя и пароль на странице входа в систему, запрашивает вход в систему, центр аутентификации sso проверяет информацию о пользователе, проверка проходит успешно, и статус сеанса помечается как «войти в систему».
@RequestMapping("/login")public String login(String username, String password, HttpServletRequest req) { this.checkLoginInfo(username, password); req.getSession().setAttribute("isLogin", true); return "success";}
скопировать код
4. sso-сервер создает токен авторизации
Токен авторизации представляет собой строку случайных символов. Неважно, как она генерируется, главное, чтобы она не повторялась и ее было нелегко подделать. Ниже приведен пример.
String token = UUID.randomUUID().toString();
скопировать код
5. sso-client получает токен и проверяет
После того, как центр аутентификации sso войдет в систему, вернитесь к подсистеме и прикрепите токен, подсистема (клиент sso) получит токен, затем перейдите в центр аутентификации sso для проверки и добавьте несколько строк в doFilter() из ЛогинФильтр.java
// 请求附带token参数String token = req.getParameter("token");if (token != null) { // 去sso认证中心校验token boolean verifyResult = this.verify("sso-server-verify-url", token); if (!verifyResult) { res.sendRedirect("sso-server-url"); return; } chain.doFilter(request, response);}
скопировать код
Метод Verify() реализован с использованием httpClient, который здесь представлен лишь кратко.
HttpPost httpPost = new HttpPost("sso-server-verify-url-with-token");HttpResponse httpResponse = httpClient.execute(httpPost);
скопировать код
6. sso-сервер получает и обрабатывает запрос токена проверки
После успешного входа пользователя в центр аутентификации sso sso-сервер создает токен авторизации и сохраняет токен, поэтому проверка токена sso-сервером заключается в том, чтобы выяснить, существует ли токен и не истек ли срок его действия. Проверка токена прошла успешно.После регистрации sso-сервером система отправляет запрос на проверку в центр сертификации sso (т.е. смысл хранения)
Токены и адреса системы регистрации обычно хранятся в базе данных «ключ-значение» (например, Redis).Redis может установить время действия ключа, которое является периодом действия токена. Redis работает в памяти и работает очень быстро, так как sso-серверу не нужно сохранять какие-либо данные.
Токены и адреса зарегистрированных систем можно хранить в redis со структурой, описанной на следующем рисунке Вы можете спросить, а зачем хранить адреса этих систем? Если он не сохранен, выйти из системы будет проблематично. Пользователь отправляет запрос на выход в центр аутентификации sso, и центр аутентификации sso выходит из глобальной сессии. Система отправляет запрос на выход, чтобы выйти из локальной сессии.
7. Токен подтверждения sso-client успешно создает локальный сеанс.
После успешной проверки токена sso-client помечает текущий локальный сеанс как «выполнивший вход», изменяет файл LoginFilter.java и добавляет несколько строк.
if (verifyResult) { session.setAttribute("isLogin", true);}
скопировать код
sso-client также должен привязать текущий идентификатор сеанса к токену, указывая, что статус входа в этот сеанс связан с токеном.Эта связь может быть сохранена с помощью хэш-карты java, и сохраненные данные используются для обработки запроса на выход отправлено центром аутентификации SSO
8. Процесс выхода
Пользователь отправляет запрос с параметром «выход» (logout request) в подсистему, а перехватчик sso-client перехватывает запрос и инициирует запрос на выход в центр аутентификации sso
String logout = req.getParameter("logout");if (logout != null) { this.ssoServer.logout(token);}
скопировать код
Центр аутентификации sso также распознает, что запрос sso-client является запросом на выход (с параметром logout) таким же образом, и центр аутентификации sso выходит из глобального сеанса.
@RequestMapping("/logout")public String logout(HttpServletRequest req) { HttpSession session = req.getSession(); if (session != null) { session.invalidate();//触发LogoutListener } return "redirect:/";}
скопировать код
В центре аутентификации SSO есть глобальный прослушиватель сеансов. После завершения глобального сеанса он уведомит все системы регистрации о необходимости выхода из системы.
public class LogoutListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent event) {} @Override public void sessionDestroyed(HttpSessionEvent event) { //通过httpClient向所有注册系统发送注销请求 }}
скопировать код
Рекомендовано в прошлом
【Технологии】Распространенные проблемы с кодом в CodeReview
【Технологии】Динамическая графика для понимания 8 алгоритмов сортировки
【Технологии】Разница между Redis и Memcached
【Технологии】Комикс: Что такое пузырьковая сортировка?
The Road to Java Architect, кружок из 60 000 технических специалистов, делает путь обучения более интересным!