为啥自动装配的 bean 为空?
Posted
技术标签:
【中文标题】为啥自动装配的 bean 为空?【英文标题】:Why autowired bean is null?为什么自动装配的 bean 为空? 【发布时间】:2018-04-16 00:22:32 【问题描述】:目标
如果用户在登录后尝试访问登录页面,则将用户重定向到主页。
方法
在过滤器级别而不是在登录控制器中重定向用户。
系统详情
JSF
春季安全
UrlRewriteFilter
详情
基于这个link我创建了一个类来访问spring security并询问用户是否登录(不是匿名用户):
public class SecurityContextAccessorImpl implements SecurityContextAccessor
@Autowired
private AuthenticationTrustResolver authenticationTrustResolver;
public SecurityContextAccessorImpl()
@Override
public boolean isCurrentAuthenticationAnonymous()
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authenticationTrustResolver.isAnonymous(authentication);
然后我开发了一个过滤器,它使用以前的类来重定向用户:
@WebFilter
@Component
public class LoginFilter implements Filter
@Autowired
private SecurityContextAccessor securityContextAccessor;
@Override
public void destroy()
// TODO Auto-generated method stub
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
if(securityContextAccessor != null)
if(securityContextAccessor.isCurrentAuthenticationAnonymous())
String contextPath = ((HttpServletRequest)request).getContextPath();
((HttpServletResponse)response).sendRedirect(contextPath + "/ASSDA/home/home");
chain.doFilter(request, response);
@Override
public void init(FilterConfig arg0) throws ServletException
// TODO Auto-generated method stub
过滤器在spring和urlrewrite之后在web.xml中定义:
<!-- ============== Spring security ============= -->
<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>
<!-- ============== UrlRewriteFilter ============= -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ============== Login Filter ============= -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>es.assda.ged.web.controller.security.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/login.xhtml</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Beans在对应的applicationContext.xml中定义
<beans:bean id="defaultTargetUrl" class="java.lang.String">
<beans:constructor-arg value="/ASSDA/home/home" />
</beans:bean>
<beans:bean id="authenticationTrustResolver" name="authenticationTrustResolver" class="org.springframework.security.authentication.AuthenticationTrustResolverImpl" />
<bean id="securityContextAccessor" name="securityContextAccessor" class="es.assda.ged.api.security.SecurityContextAccessorImpl" />
当前行为
重定向做得很好并到达了 LoginFilter,但自动连接的 securityContextAccessor 变量没有被初始化。我认为它没有初始化,因为 bean authenticationTrustResolver 为空。
另一方面,如果我在登录控制器中声明自动装配变量 securityContextAccessor,它会被正确注入。
为什么在 LoginFilter 中 securityContextACcessor 为 null 并在登录控制器中正确实例化?
【问题讨论】:
没有注入 bean 可能是因为它不是由 Spring 管理的。这可能是由于@WebFilter
使您的过滤器由 JEE 容器管理。
【参考方案1】:
看起来你没有通过 Spring 实例化你的 Filter
,所以你没有得到依赖注入。它应该使用DelegatingFilterProxy:
web.xml:
<filter>
<filter-name>springLoginFilter</filter-name><!-- Your filter bean in Spring -->
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
applicationContext.xml:
<bean id="springLoginFilter" class="es.assda.ged.web.controller.security.LoginFilter" />
另外,请参阅Accessing Spring beans from servlet filters and tags
【讨论】:
以上是关于为啥自动装配的 bean 为空?的主要内容,如果未能解决你的问题,请参考以下文章