предисловие
Единая регистрация широко распространена в текущей архитектуре системы. Она открывает системы аутентификации нескольких подсистем и реализует использование одной записи в нескольких местах. При построении единой регистрации также возникнут небольшие проблемы, которые могут могут использоваться в разных приложениях.В среде могут использоваться различные реализации единого входа в соответствии с потребностями.
1. Общий сеанс
Общий сеанс можно охарактеризовать как наиболее прямой и простой способ достижения единого входа. Сохраните информацию об аутентификации пользователя в сеансе, то есть используйте значение, хранящееся в сеансе, в качестве учетных данных пользователя.Это нормально и легко использовать на одном сайте, но в сценарии, где аутентификация пользователя, управление информацией о пользователях и бизнес-приложения разделены То есть возникнет проблема единого входа.Когда прикладная система проста и имеется несколько подсистем, для решения этой проблемы можно рассмотреть метод совместного использования сеансов.
Для этой архитектуры я использую схему совместного использования сеансов на основе Redis. Сохраните сеанс в Redis, а затем установите глобальный домен cookie всей системы на имя домена верхнего уровня, чтобы идентификатор сеанса мог совместно использоваться различными подсистемами. Распределенное решение для совместного использования сеансов, эту статью рекомендуется прочитать всем.
Это решение имеет серьезные проблемы с масштабируемостью.Во-первых, хранилище сеансов ASP.NET должно быть объектом SessionStateItemCollection, а структура хранилища шифруется и сохраняется после сериализации.
И когда пользователь обращается к приложению, первое, что он делает, — это извлекает весь контент из контейнера хранилища и десериализует его в объект SessionStateItemCollection.
Это определяет, что он имеет следующие ограничения:
1. Типы, задействованные в сеансе, должны совместно использоваться подсистемами (то есть сборки и типы должны быть согласованы), что приводит к множеству ограничений на использование сеанса;
2. Ситуацию с перекрестными доменными именами верхнего уровня вообще нельзя разрешить;
2. Единый вход на основе OpenId
Этот единый вход упрощает идентификацию пользователя как OpenId и сохраняет ее на клиенте. Когда пользователь входит в подсистему, OpenId передается на сервер. Сервер создает информацию для аутентификации пользователя на основе OpenId, которая в основном используется в комбинированной системе C / S и B / S, процесс выглядит следующим образом:
Как видно из приведенного выше рисунка, этот набор единого входа основан на передаче OpenId, а его проверка основана на хранении и передаче OpenId.
1. Когда пользователь входит в систему в первый раз, отправьте имя пользователя и пароль в службу проверки;
2. Служба аутентификации возвращает идентификатор пользователя OpenId клиенту;
3. Магазины клиента;
4. При обращении к подсистеме отправить OpenId в подсистему;
5. Подсистема пересылает OpenId службе верификации;
6. Служба аутентификации возвращает подсистеме информацию об аутентификации пользователя;
7. После того, как подсистема создаст информацию для аутентификации пользователя, она возвращает авторизованный контент клиенту.
Основная проблема этого механизма аутентификации единого входа заключается в том, что он хранит OpenId пользователя на клиенте на основе архитектуры C/S и отправляет OpenId между подсистемами, но в режиме B/S это сделать сложнее. . . . Чтобы решить эту проблему, мы представим следующий метод, который решит проблему хранения и передачи OpenId в режиме B/S.
3. Решение для хранения OpenId на основе файлов cookie
Мы знаем, что роль файлов cookie заключается в том, чтобы выступать в качестве носителя информации для передачи информации между сервером и стороной браузера, и файлы cookie обычно делятся по доменным именам, например, файлы cookie a.xxx.com и b.xxx. com не могут получить доступ друг к другу. , но поддомен может получить доступ к файлам cookie домена верхнего уровня. То есть a.xxx.com и b.xxx.com могут получить доступ к файлам cookie под xxx.com, поэтому файлы cookie доменного имени верхнего уровня могут использоваться в качестве носителя OpenId.
Шаги проверки очень похожи на второй способ выше:
1. Войдите на сайт, предоставляющий услуги проверки;
2. Запишите OpenId в файл cookie домена верхнего уровня;
3. Подсистема доступа (с OpenId в куки)
4. Подсистема берет OpenId и отправляет OpenId в службу верификации
5. Вернуть информацию для аутентификации пользователя
6. Вернуть авторизованный контент
В приведенных выше двух методах мы видим, что типы и другие проблемы в схеме совместного использования сеансов развязаны через OpenId, и построение информации для аутентификации пользователя будет более гибким, а проверка между подсистемами независима друг от друга, но в третья схема Здесь мы предполагаем, что все подсистемы имеют одно и то же доменное имя верхнего уровня, и наличие нескольких доменных имен в реальной производственной среде является нормальным явлением, поэтому мы должны рассмотреть, как решить междоменную проблему.
4. Обработка единого входа в мультидоменной среде B/S
В случае нескольких доменов верхнего уровня мы не сможем совместно использовать OpenId различных подсистем. Чтобы справиться с междоменными проблемами в среде B/S, мы должны сначала подумать о решении JSONP.
Этапы проверки следующие:
1. Пользователь входит в систему через подсистему входа в систему;
2. Подсистема входа пользователя записывает статус входа пользователя, OpenId и другую информацию;
3. Пользователи используют бизнес-подсистему;
4. Если пользователь не входит в бизнес-подсистему, он будет перенаправлен в подсистему входа пользователя;
5. Пользовательская подсистема передает пользовательский OpenId в бизнес-подсистему через интерфейс JSONP;
6. Бизнес-подсистема вызывает службу верификации через OpenId;
7. Служба проверки возвращает информацию об аутентификации, а бизнес-подсистема создает учетные данные пользователя для входа в систему (в это время пользовательский клиент уже полностью соответствует проверочной информации подсистемы бизнеса).
8. Вернуть результат входа пользователя в подсистему входа пользователя, и если вход будет успешным, пользователь будет перенаправлен обратно в бизнес-подсистему;
9. Вернуть авторизованный контент клиенту;
5. Вопросы безопасности
После вышеуказанных шагов проблема единого входа в междоменной ситуации может быть решена. На ранней стадии всего процесса разработки мы использовали поле OpenId в пользовательской таблице для сохранения OpenId пользователя, и этот механизм, очевидно, имеет некоторые проблемы с безопасностью и масштабируемостью. Эта проблема масштабируемости в основном отражается в одном аспекте: противоречие между безопасностью OpenId и пользовательским опытом.
Весь механизм единого входа определяет, что OpenId будет отображаться на стороне клиента, поэтому OpenId должен иметь механизм истечения срока действия.Если пользователь входит в систему на одном терминале, он может выбрать обновление OpenId каждый раз, когда пользователь входит в систему или входит в систему. выход и авторизация на нескольких терминалах, будет противоречие в случае: когда один терминал обновляет OpenId, другие терминалы не смогут нормально авторизоваться.
В конце концов, я принял однопользовательское решение с несколькими OpenId. Каждый раз, когда пользователь входит в систему с именем пользователя/паролем, OpenId генерируется и сохраняется в Redis, а также устанавливается время истечения срока действия. Таким образом, несколько входов в терминал будут иметь несколько соответствующих им OpenId, и больше не будет одного OpenId недействителен. Выполнены все проверки терминала. Ситуация сбоя.
Наконец
Прошу всех обратить внимание на мой паблик [Программист в погоне за ветром], в нем будут обновляться статьи, а также размещаться отсортированная информация.