Введенный HttpServletRequest в UserDetailsService - это не завернутый HttpServletRequest, добавленный фильтром?

Как я могу поместить свой собственный фильтр, который обертывает HttpServletRequest с помощью HttpServletRequestWrapper, чтобы HttpServletRequest, который является @Autowired, в моем настраиваемом UserDetailsService, чтобы он видел обернутый HttpServletRequest вместо обычного HttpServletRequest?

Позвольте мне попытаться объяснить: в моем настраиваемом фильтре я анализирую поддомен и домен и помещаю полезную информацию в HttpServletRequest, обертывая ее с помощью HttpServletRequestWrapper и переопределяя getHeader().

Но когда я вводил HttpServletRequest с использованием @Autowired в UserDetailsService, введенный HttpServletRequest не является обернутым и не содержит информации, добавленной моим настраиваемым фильтром.

В моем web.xml я поставил свой фильтр первым перед всеми пружинными фильтрами (ContextLoaderListener, RequestContextListener и DelegatingFilterProxy), поэтому мой фильтр должен быть первым встроенным. Это заставляет меня задуматься.

Обратите внимание, что когда я вставляю HttpServletRequest в обычный контроллер, он вводит упакованный HttpServletRequest. UserDetailsService может быть особым случаем.

У кого-нибудь есть блестящая идея?

Как выставить HttpServletRequest? Покажите свой web.xml.

dur 23.04.2018 21:26

@dur my web.xml содержит фильтры и стандартные весенние материалы, которые есть в каждом весеннем приложении. И spring предоставляет HttpServletRequest, я просто вводю с помощью Autowired. Обратите внимание, что, как указано в моем сообщении, инъекция работает должным образом в обычных контроллерах, но не в UserDetailsService, что заставляет меня думать, что с конфигурацией все в порядке, но UserDetailsService - особый случай. Но я не могу найти много связанного с HttpServletRequestWrapper и UserDetailsService.

Tinus Tate 23.04.2018 23:32

Есть три способа раскрыть HttpServletRequest. Вы должны использовать правильный путь. Покажите свой web.xml.

dur 23.04.2018 23:50

Не делай этого. Ваш UserDetailsService не должен ничего знать о том, что он работает внутри веб-приложения. Вместо этого вам следует поместить так называемые детали в ваш Authentication, которые содержат необходимую дополнительную информацию. См. UsernamaPasswordFilter, который использует WebAuthenticationDetails по умолчанию для передачи информации. Вы можете создать свой собственный AuthenticationDetailsSource и заполнить свой собственный объект сведений необходимой информацией.

M. Deinum 24.04.2018 08:08

Ура @ M.Deinum, я попробовал, но аутентификация (используемая для auth.getDetails ()) всегда имеет значение null в моем loadUserByUsername в UserDetailsService, что имеет смысл, потому что пользователь еще не аутентифицирован. Хотя я вижу, что MyWebAuthenticationDetails вызывается перед loadUserByUsername, но, похоже, нет способа получить WebAuthenticationDetails в loadUserByUsername?

Tinus Tate 24.04.2018 10:09

Он должен быть частью передаваемого в Authentication, если это не вы делаете странные вещи в своем потоке.

M. Deinum 24.04.2018 10:11

@ M.Deinum спасибо, UserDetailsService не имеет доступа к аутентификации, это интерфейс с 1 функцией loadUserByUsername. Я также пытался получить его из SecurityContextHolder, но это значение null. Заглянув немного дальше, возможно ли, что мне нужно реализовать настраиваемый AuthenticationProvider, который имеет доступ к Authentication в качестве параметра метода аутентификации.

Tinus Tate 24.04.2018 10:22

Виноват. Думал о более высоком уровне с DaoAuthenticationProvider. Что вам нужно / что вы хотите сделать с дополнительной информацией (как правило, вам следует делать это не на вашем UserDetailsService в первую очередь, а на самом деле на вашем AuthenticationProvider, или путем расширения безопасности Spring с помощью интерфейсов обратного вызова.

M. Deinum 24.04.2018 10:48

Ура @ M.Deinum, я собираюсь попробовать собственный AuthenticationProvider.

Tinus Tate 24.04.2018 12:17

Он вам не нужен, какой вариант использования вы пытаетесь реализовать?

M. Deinum 24.04.2018 13:34

Это довольно сложно, но небольшая часть - это то, какая база данных пользователей, которую я выбираю, зависит от поддомена / домена в запросе и от того, какой поддомен / домен известен только во время выполнения и может измениться. Поскольку мой фильтр уже помещает полезную информацию в HttpServletRequestWrapper для настраиваемого сопоставления запросов, и я подумал, что могу также использовать его для аутентификации. Обратите внимание, как темп. решение Теперь я помещаю конкретную информацию в атрибут запроса, который может прочитать мой UserDetailsService. Немного взлома и дублирование данных, я признаю. Я скоро отправлю ответ. Я ценю вашу помощь!

Tinus Tate 24.04.2018 14:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
11
126
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что HttpServletRequest, введенный в UserDetailsService, отличается от обычных контроллеров.

В обычных контроллерах вызов request.getHeader приводит к вызову обернутого request.getHeader. В UserDetailsService это не так. Я подозреваю, что HttpServletRequest в UserDetailsService является копией и не обертывает / прокси вокруг исходного HttpServletRequest, возможно, его нужно сериализовать.

Но счастливчик может использовать request.setAttribute, атрибуты запроса доступны во внедренном HttpServletRequest в UserDetailsService и обычных контроллерах.

Обратите внимание, что это немного взломано. В зависимости от вашего варианта использования вы можете прочитать интересные комментарии @M. Deinum и перейдите по маршруту AuthenticationProvider с данными в настраиваемом WebAuthenticationDetails, который создается настраиваемым AuthenticationDetailsSource.

Другие вопросы по теме