dev*_*dev 24 security spring servlets ioc-container security-context
我有一个spring bean(dao)对象,我通过以下xml在我的ServletContext中实例化:
<bean id="userDao" class="com.company.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Run Code Online (Sandbox Code Playgroud)
这个bean在我的webapp-servlet.xml文件中声明,并由我的应用程序在ServletContext中使用.
我也在使用SpringSecurity.我的理解是,它在不同的上下文中运行(SecurityContext).
我的应用程序有一个webapp-security.xml,我在其中实例化一个自定义身份验证提供程序.我想使用我的应用程序中使用的我的dao也在我的安全上下文中进行用户查找,但是当我运行时:
<bean id="userAuthenticationProvider" class="com.company.security.UserAuthenticationProvider">
<property name="userDao" ref="userDao" />
</bean>
Run Code Online (Sandbox Code Playgroud)
我得到错误,说没有这样的bean"userDao".bean在我的其他上下文中声明的bean中自动装配好,但不在我的安全上下文中.根据Spring Docs,我相信web.xml中需要两个单独的上下文
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何才能访问我的SecurityContext中存在于我的ServletContext中的DAO?我的dao是否有范围修饰符,或者我可以在运行时在我的身份验证提供程序中以某种方式获取ServletContext?作为参考,这是我想在我的身份验证提供程序中使用它的方式:
public class UserAuthenticationProvider extends
AbstractUserDetailsAuthenticationProvider {
@Override
protected UserDetails retrieveUser(String userName,
UsernamePasswordAuthenticationToken authenticationToken)
throws AuthenticationException {
// use dao here
Run Code Online (Sandbox Code Playgroud)
谢谢你向我解释这个
更新:
继续我的调查,似乎我使用我的daos的DispatcherServlet是一个子上下文,安全上下文在某个更高的位置.因此,父上下文无法看到我的DispatcherServlet中的bean.我认为答案是以某种方式将我的bean声明移动到父应用程序上下文中,但我不知道如何做到这一点.这是我的web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
...
Run Code Online (Sandbox Code Playgroud)
我将我的所有dao创建移动到spring-dao.xml,在我的spring-security.xml中,我现在正在执行:
<import resource="spring-dao.xml" />
Run Code Online (Sandbox Code Playgroud)
daos stil对DispatcherServlet上下文仍然可见,但对我的SecurityContext不可见.
回答说:
好吧,我明白了.以下是一些有用的链接:
http://static.springsource.org/spring-security/site/faq.html#faq-method-security-in-web-context
所以问题是我们需要确保dao存在于ApplicationContext中(更高的弹簧容器).为了确保发生这种情况,我将web.xml更改为:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-dao.xml WEB-INF/spring-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>webapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)
我认为这将确保启动的第一个上下文加载器将读取我的dao配置(并创建我的dao bean),然后是我的安全配置.由于以这种方式创建了dao bean,因此我删除了security.xml中之前的"import resource ="spring-dao.xml""语句,因为它将不再需要.
在context-param配置之后,我创建了ContextLoaderListener.这是一个比DispatcherServlet更高级的弹簧容器,所以我认为这首先是第一个读取这些配置文件的人,然后他会创建bean.然后,任何子上下文都可以访问它们.这可能不是它的工作方式,因为DispatcherServlet甚至可能都没有读取contextConfigLocation,但即使它确实如此,我认为此时bean已经被声明,所以太糟糕了,父上下文拥有它们.
现在,换另一招......为了获得我的DAO,我无法 @Autowired它.我不得不通过XML手动注入它:
<bean id="userAuthenticationProvider" class="com.company.app.security.UserAuthenticationProvider">
<property name="userDao" ref="userDao" />
</bean>
Run Code Online (Sandbox Code Playgroud)
当然,我在我的dao上制作了getter和setter方法,瞧!我不知道为什么@Autowired在这里不起作用.我认为它是设计的.也许这对于SecurityContext来说是特别的(它不会从其他上下文中提取),或者@Autowired通常只从当前上下文中提取,或者可能是因为我通过XML创建了bean,我还必须通过xml设置任何属性,不是通过注释?(注释已启用并在我的顶级应用程序命名空间中工作).
无论如何..仍然很多我不明白,但重要的是它终于工作了.
Rya*_*art 60
如果你打算使用Spring MVC,你肯定需要了解Spring MVC的ApplicationContext层次结构.您还应该了解servlet容器中的基本组件和生命周期,因为您似乎也对监听器和servlet的工作方式感到困惑.
简要解释一下你的情况:
<context:component-scan/>或<context:annotation-config/>在该bean存在的上下文中.| 归档时间: |
|
| 查看次数: |
26717 次 |
| 最近记录: |