После того, как новый пользователь отправит форму «Новая учетная запись», я хочу вручную выполнить вход для этого пользователя, чтобы ему не приходилось входить на следующей странице.
Обычная страница входа в систему, проходящая через перехватчик безопасности Spring, работает нормально.
В контроллере формы новой учетной записи я создаю UsernamePasswordAuthenticationToken и вручную устанавливаю его в SecurityContext:
SecurityContextHolder.getContext().setAuthentication(authentication);
На этой же странице я позже проверяю, что пользователь вошел в систему с:
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Это возвращает полномочия, которые я установил ранее при аутентификации. Все хорошо.
Но когда этот же код вызывается на следующей странице, которую я загружаю, токен аутентификации будет просто UserAnonymous.
Я не понимаю, почему он не сохранил аутентификацию, которую я установил в предыдущем запросе. Есть предположения?
- Может ли это быть связано с неправильной настройкой идентификатора сеанса?
- Есть ли что-то, что может как-то перезаписать мою аутентификацию?
- Возможно, мне просто нужен еще один шаг, чтобы сохранить аутентификацию?
- Или мне нужно что-то сделать, чтобы как-то объявить аутентификацию для всего сеанса, а не для одного запроса?
Просто ищу некоторые мысли, которые могут помочь мне увидеть, что здесь происходит.
источник
SecurityContextHolder.getContext().setAuthentication(authentication)
. Это работает и является обычным явлением, но есть серьезные функциональные недостатки, с которыми вы столкнетесь, если просто сделаете это. Для получения дополнительной информации см. Мой вопрос и ответ: stackoverflow.com/questions/47233187/…Ответы:
Некоторое время назад у меня была такая же проблема, как и у вас. Я не могу вспомнить детали, но следующий код помог мне. Этот код используется в потоке Spring Webflow, отсюда и классы RequestContext и ExternalContext. Но наиболее важная для вас часть - это метод doAutoLogin.
источник
@Configuration public class WebConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationProvider() throws Exception { return super.authenticationManagerBean(); } }
Я не мог найти других полных решений, поэтому решил опубликовать свое. Это может быть чем-то вроде взлома, но он решил проблему с вышеуказанной проблемой:
источник
authenticationManager
?В конечном итоге выяснили корень проблемы.
Когда я создаю контекст безопасности вручную, объект сеанса не создается. Только когда запрос завершает обработку, механизм Spring Security понимает, что объект сеанса имеет значение NULL (когда он пытается сохранить контекст безопасности для сеанса после обработки запроса).
В конце запроса Spring Security создает новый объект сеанса и идентификатор сеанса. Однако этот новый идентификатор сеанса никогда не попадает в браузер, потому что он появляется в конце запроса, после того, как браузер получил ответ. Это приводит к потере нового идентификатора сеанса (и, следовательно, контекста безопасности, содержащего моего зарегистрированного вручную пользователя), когда следующий запрос содержит идентификатор предыдущего сеанса.
источник
Включите ведение журнала отладки, чтобы лучше понять, что происходит.
Вы можете узнать, устанавливаются ли файлы cookie сеанса, используя отладчик на стороне браузера, чтобы просмотреть заголовки, возвращаемые в ответах HTTP. (Есть и другие способы.)
Одна из возможностей состоит в том, что SpringSecurity устанавливает файлы cookie безопасного сеанса, и ваша следующая запрашиваемая страница имеет URL-адрес http вместо URL-адреса https. (Браузер не отправляет безопасный файл cookie для URL-адреса "http".)
источник
Новая функция фильтрации в Servlet 2.4 в основном снимает ограничение, согласно которому фильтры могут работать только в потоке запросов до и после фактической обработки запроса сервером приложений. Вместо этого фильтры Servlet 2.4 теперь могут взаимодействовать с диспетчером запросов в каждой точке отправки. Это означает, что когда веб-ресурс пересылает запрос другому ресурсу (например, сервлет, пересылающий запрос на страницу JSP в том же приложении), фильтр может работать до того, как запрос будет обработан целевым ресурсом. Это также означает, что если веб-ресурс включает вывод или функцию из других веб-ресурсов (например, страницу JSP, включающую вывод нескольких других страниц JSP), фильтры Servlet 2.4 могут работать до и после каждого из включенных ресурсов. .
Чтобы включить эту функцию, вам необходимо:
web.xml
RegistrationController
источник
Я пытался протестировать приложение extjs, и после успешной установки testingAuthenticationToken оно внезапно перестало работать без очевидной причины.
Я не мог заставить приведенные выше ответы работать, поэтому моим решением было пропустить этот кусочек весны в тестовой среде. Я сделал такой шов вокруг пружины:
Пользователь здесь - это настраиваемый тип.
Затем я помещаю его в класс, у которого просто есть возможность для тестового кода переключать пружину.
Тестовая версия выглядит примерно так:
В вызывающем коде я все еще использую правильного пользователя, загруженного из базы данных:
Очевидно, это не подходит, если вам действительно нужно использовать безопасность, но я использую настройку без безопасности для тестового развертывания. Я думал, что кто-то другой может столкнуться с подобной ситуацией. Это шаблон, который я раньше использовал для имитации статических зависимостей. Другая альтернатива - вы можете поддерживать статичность класса-оболочки, но я предпочитаю этот, поскольку зависимости кода более явны, поскольку вам нужно передать CurrentUserAccessor в классы, где это требуется.
источник