У меня есть объект Spring bean (dao), который я создаю в моем ServletContext через следующий xml:
Этот bean объявлен внутри моего сервлета webapp. xml и используется моим приложением в ServletContext.
Я также использую SpringSecurity. Насколько я понимаю, это выполняется в другом контексте (SecurityContext).
В моем приложении есть файл webapp-security.xml, где Я создаю экземпляр настраиваемого поставщика аутентификации. Я хотел бы использовать свой dao, который используется в моем приложении, чтобы также выполнять поиск пользователей в моем контексте безопасности, но когда я запускаю:
я получаю сообщение об отсутствии такого bean-компонента » userDao ". Компонент автоматически подключается к bean-компонентам, объявленным в другом моем контексте, но не внутри моего контекста безопасности. Согласно Spring Docs, я не верю В web.xml
org.springframework.web.context.ContextLoaderListener
org.springframework.security.web.session.HttpSessionEventPublisher
необходимы оба отдельных контекста. Итак, мой вопрос: как мне получить доступ к моему DAO, который находится в моем ServletContext внутри моего SecurityContext? Есть ли модификатор области действия для моего dao, или я могу каким-то образом получить ServletContext во время выполнения в моем провайдере аутентификации? Для справки, вот как я хочу использовать его внутри своего провайдера аутентификации:
public class UserAuthenticationProvider extends
AbstractUserDetailsAuthenticationProvider {
@Override
protected UserDetails retrieveUser(String userName,
UsernamePasswordAuthenticationToken authenticationToken)
throws AuthenticationException {
// use dao here
спасибо за объяснение мне
ОБНОВЛЕНИЕ:
Продолжая мое расследование, кажется, что DispatcherServlet, в котором я использую свой daos, является дочерний контекст, а контекст безопасности где-то выше.Следовательно, bean-компоненты в моем DispatcherServlet не могут быть просмотрены родительскими контекстами. Я думаю, что ответ состоит в том, чтобы как-то переместить мои объявления bean в контекст родительского приложения, но я не уверен, как это сделать. Вот мой web.xml
contextConfigLocation
WEB-INF/spring-*.xml
org.springframework.security.web.session.HttpSessionEventPublisher
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
myapp
org.springframework.web.servlet.DispatcherServlet
1
listings
true
...
. Я переместил все свое создание dao в spring-dao.xml, а в моем spring-security.xml я теперь делаю:
daos stil остается видимым для DispatcherServlet контекст и невидимый для моего SecurityContext.
ОТВЕТИЛ:
Хорошо, я разобрался. Вот несколько полезных ссылок:
http://static.springsource.org/spring-security/site/faq.html # faq-method-security-in-web-context
Итак, проблема заключалась в том, что нам нужно было убедиться, что дао существует в ApplicationContext (верхний весенний контейнер). Чтобы убедиться, что это произошло, я изменил свой web.xml на:
contextConfigLocation
WEB-INF/spring-dao.xml WEB-INF/spring-security.xml
org.springframework.web.context.ContextLoaderListener
org.springframework.security.web.session.HttpSessionEventPublisher
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
webapp
org.springframework.web.servlet.DispatcherServlet
1
listings
true
Я думал, что это гарантирует, что первый загрузчик контекста, который запускается, прочитает мою конфигурацию dao (и создаст мои bean-компоненты dao), а затем мою конфигурацию безопасности. Поскольку компоненты dao создаются таким образом, я удалил предыдущий оператор import resource = "spring-dao.xml" "в security.xml, потому что он больше не понадобится.
Сразу после настройки параметров контекста я создал ContextLoaderListener.Это контейнер Spring более высокого уровня, чем DispatcherServlet, поэтому я решил, что если он будет первым, он будет первым, кто прочитает эти файлы конфигурации, а затем он создаст bean-компоненты. Тогда любой дочерний контекст получит к ним доступ. Это может быть не так, как это работает, поскольку DispatcherServlet может даже не читать contextConfigLocation, но даже если это так, я подумал, что на этом этапе bean-компоненты уже будут объявлены, так что жаль, что родительский контекст владеет ими.
Теперь, еще один трюк ... чтобы получить мой DAO, я мог не @Autowired его. Мне пришлось вручную ввести его через XML:
Конечно, я сделал методы получения и установки на моем дао, и вуаля! Я не знаю, почему здесь не работает @Autowired. Я предполагаю, что это задумано. Возможно, это характерно для SecurityContext (он не будет извлекаться из других контекстов), или, возможно, @Autowired в целом только извлекает из текущего контекста, или, может быть, потому, что я создал bean-компонент через XML, я также должен устанавливать какие-либо свойства через xml, а не через аннотации? (аннотации включены и работают в моем пространстве имен приложения верхнего уровня).
В любом случае ... я еще многого не понимаю, но важно то, что он наконец-то заработал.