Весна. Джава. Войти и активировать электронную почту
У меня проблема с "куриным яйцом". В приложении я использую UserDetailsService для получения пользователя (мы не храним информацию о пользователях в нашей БД, мы используем сторонние сервисы, чтобы фактически получить всю информацию).
Недавно мы добавили функцию активации учетной записи. После регистрации мы отправляем пользователю электронное письмо с кодом активации и, если он нажимает на него, мы помечаем пользователя как АКТИВНОГО и перенаправляем его на страницу входа. Пользователь может войти, только если у него есть АКТИВНЫЙ статус. Проблема в том, что мы начнем взимать плату с пользователя, который активирует свою учетную запись, даже если он никогда не будет входить в систему. Как я могу (возможно, используя Spring Security) сделать эти процессы (активация и вход в систему) практически одновременными? Мы не хотим взимать плату с пользователя, если он просто активирует свою учетную запись, мы хотим взимать с него плату только в том случае, если он вошел в систему (после активации). Так что я могу сделать это как-то "пользователь нажимает на ссылку активации, входит в систему, а затем его статус меняется на ACTIVE (но он может войти, только если он ACTIVE)".
Извините, если описание моей проблемы недостаточно ясное
Буду признателен за любые отзывы.
Спасибо!
1 ответ
Если я правильно понял ваши требования, вам понадобятся две разные точки входа (страницы входа) в ваше приложение:
- Один для активации (первый вход в систему) для пользователей, которые еще не активированы.
- Еще один "нормальный" для активных пользователей.
Проблема заключается в том, что логика аутентификации должна быть контекстно-зависимой и знать, какая из вышеуказанных страниц инициировала аутентификацию. Однако структура не была разработана для таких необычных сценариев использования, поэтому поставщик аутентификации не знает об URL-адресе, с которого фактически была отправлена форма входа.
Вам нужно решить, как-то передать контекстную информацию провайдеру аутентификации, который обрабатывает запрос на аутентификацию в соответствии с этой информацией (то есть аутентифицировать только неактивных пользователей, которые входят в систему с url1, и аутентифицировать только активных пользователей, которые входят в систему с url2). Для достижения этой цели могут быть сотни различных способов. Одно из возможных решений - установить два разных фильтра аутентификации, которые перехватывают запросы на аутентификацию, отправленные на два разных URL-адреса. Подробности изложены ниже:
- Создайте свои собственные версии существующих
WebAuthenticationDetailsSource
а такжеWebAuthenticationDetails
(предпочтительно путем подкласса последнего), который хранит и предоставляет URI запроса аутентификации. (Это будет контекстная информация, на основе которой поставщик аутентификации может реализовать свою условную логику.) - Сконфигурируйте и вставьте два разных экземпляра
UsernamePasswordAuthenticationFilter
в цепочке фильтров. Установить ихfilterProcessesUrl
приписывать/j_spring_security_check_active_user
а также/j_spring_security_check_nonactive_user
соответственно плюс добавляем созданный выше кастомAuthenticationDetailsSource
в них обоих. - Override
DaoAuthenticationProvider.additionalAuthenticationChecks()
в подклассе следующим образом:- Получить URI, сохраненный в созданном выше
WebAuthenticationDetails
объект (это доступно черезauthentication.getDetails()
) - Утвердите, что пользователь активен / неактивен в соответствии с URI, и бросьте
AccountStatusException
если сборка не удалась. - Не забудьте делегировать суперклассу, если утверждение выполнено успешно.
- Получить URI, сохраненный в созданном выше
- Создайте две разные страницы входа, упомянутые в начале сообщения, убедившись, что при входе в учетную запись формируются учетные данные для публикации с соответствующим URL (
/j_spring_security_check_nonactive_user
против/j_spring_security_check_active_user
).