Весна. Джава. Войти и активировать электронную почту

У меня проблема с "куриным яйцом". В приложении я использую UserDetailsService для получения пользователя (мы не храним информацию о пользователях в нашей БД, мы используем сторонние сервисы, чтобы фактически получить всю информацию).

Недавно мы добавили функцию активации учетной записи. После регистрации мы отправляем пользователю электронное письмо с кодом активации и, если он нажимает на него, мы помечаем пользователя как АКТИВНОГО и перенаправляем его на страницу входа. Пользователь может войти, только если у него есть АКТИВНЫЙ статус. Проблема в том, что мы начнем взимать плату с пользователя, который активирует свою учетную запись, даже если он никогда не будет входить в систему. Как я могу (возможно, используя Spring Security) сделать эти процессы (активация и вход в систему) практически одновременными? Мы не хотим взимать плату с пользователя, если он просто активирует свою учетную запись, мы хотим взимать с него плату только в том случае, если он вошел в систему (после активации). Так что я могу сделать это как-то "пользователь нажимает на ссылку активации, входит в систему, а затем его статус меняется на ACTIVE (но он может войти, только если он ACTIVE)".

Извините, если описание моей проблемы недостаточно ясное

Буду признателен за любые отзывы.

Спасибо!

1 ответ

Если я правильно понял ваши требования, вам понадобятся две разные точки входа (страницы входа) в ваше приложение:

  1. Один для активации (первый вход в систему) для пользователей, которые еще не активированы.
  2. Еще один "нормальный" для активных пользователей.

Проблема заключается в том, что логика аутентификации должна быть контекстно-зависимой и знать, какая из вышеуказанных страниц инициировала аутентификацию. Однако структура не была разработана для таких необычных сценариев использования, поэтому поставщик аутентификации не знает об URL-адресе, с которого фактически была отправлена ​​форма входа.

Вам нужно решить, как-то передать контекстную информацию провайдеру аутентификации, который обрабатывает запрос на аутентификацию в соответствии с этой информацией (то есть аутентифицировать только неактивных пользователей, которые входят в систему с url1, и аутентифицировать только активных пользователей, которые входят в систему с url2). Для достижения этой цели могут быть сотни различных способов. Одно из возможных решений - установить два разных фильтра аутентификации, которые перехватывают запросы на аутентификацию, отправленные на два разных URL-адреса. Подробности изложены ниже:

  1. Создайте свои собственные версии существующих WebAuthenticationDetailsSource а также WebAuthenticationDetails (предпочтительно путем подкласса последнего), который хранит и предоставляет URI запроса аутентификации. (Это будет контекстная информация, на основе которой поставщик аутентификации может реализовать свою условную логику.)
  2. Сконфигурируйте и вставьте два разных экземпляра UsernamePasswordAuthenticationFilter в цепочке фильтров. Установить их filterProcessesUrl приписывать /j_spring_security_check_active_user а также /j_spring_security_check_nonactive_user соответственно плюс добавляем созданный выше кастом AuthenticationDetailsSource в них обоих.
  3. Override DaoAuthenticationProvider.additionalAuthenticationChecks() в подклассе следующим образом:
    • Получить URI, сохраненный в созданном выше WebAuthenticationDetails объект (это доступно через authentication.getDetails())
    • Утвердите, что пользователь активен / неактивен в соответствии с URI, и бросьте AccountStatusException если сборка не удалась.
    • Не забудьте делегировать суперклассу, если утверждение выполнено успешно.
  4. Создайте две разные страницы входа, упомянутые в начале сообщения, убедившись, что при входе в учетную запись формируются учетные данные для публикации с соответствующим URL (/j_spring_security_check_nonactive_user против /j_spring_security_check_active_user).
Другие вопросы по тегам