【问题标题】:NullPointerException at org.springframework.security.web.FilterChainProxy.getFiltersorg.springframework.security.web.FilterChainProxy.getFilters 处的 NullPointerException
【发布时间】:2015-10-01 23:49:16
【问题描述】:

我尝试使用 spring-security,并收到此错误。

java.lang.NullPointerException
at org.springframework.security.web.FilterChainProxy.getFilters(FilterChainProxy.java:223)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:196)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

我在 web.xml 中包含过滤器

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encoding-filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  <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>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<display-name>Spring MVC Application</display-name>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

并在 applicationContext 文件中为这个过滤器创建一个 bean:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> </bean>

在我在 applicationContext 文件中注册这个 bean 之前,我有一个错误 no bean named 'springSecurityFilterChain' is defined

我不使用spring-security.xml进行配置,在SecurityConfig类中配置安全性。

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Autowired
public void registerGlobalAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .userDetailsService(userDetailsService);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/resources/**", "/**").permitAll()
            .anyRequest().permitAll()
            .and();

    http.formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/j_spring_security_check")
            .failureUrl("/login?error")
            .usernameParameter("j_username")
            .passwordParameter("j_password")
            .permitAll();

    http.logout()
            .permitAll()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout")
            .invalidateHttpSession(true);

}   

}

我认为这是 spring-security 文件配置的一些问题,但我不明白出了什么问题。

【问题讨论】:

  • web.xml中的/*,在后面对吗?
  • @melli-182 是的,我认为这是正确的
  • 但是发表评论,它会导致过滤器映射和 url-pattern 标记永远不会关闭。
  • @melli-182 不,这不是注释,它看起来像代码部分中的注释,在 .xml 中这是 (/*) 不是 cmets 的符号
  • 你看过这个stackoverflow.com/questions/23572516/… 吗?如果您只使用 xml 或 java 配置,也许会更容易。

标签: java spring spring-mvc filter spring-security


【解决方案1】:

我已经弄清楚这里发生了什么,但我认为你最好只坚持 Java 配置或 XML 配置,而不是在集成 Spring MVC 和安全性方面混合和匹配它们。

在 XML 配置中,springSecurityFilterChain 由 spring-security.xml 中的 http 命名空间创建。请参阅here。由于您已切换到 java 配置,因此没有创建 springSecurityFilterChain,这正是应用程序所抱怨的。

要在其中创建 springSecurityFilterChain,您需要执行以下 2 个步骤。

第 1 步

从您的 web.xml 中删除以下内容

 <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>

第 2 步

创建一个AbstractSecurityWebApplicationInitializer,它将为您创建 springsecurityfilterchain。

public class SpringSecurityInitializer extends
        AbstractSecurityWebApplicationInitializer {
}

现在AbstractSecurityWebApplicationInitializer documentation 这么说 当与 AbstractSecurityWebApplicationInitializer() 一起使用时,该类通常与 AbstractContextLoaderInitializer 的子类一起使用。

所以现在你必须自己创建 AbstractContextLoaderInitializer。为此,我做了 2 处更改

第 1 步:- 从 web.xml 中删除以下内容

   <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
        </param-value>

第 2 步:- 创建一个类 SpringAnnotationWebInitializerApplicationContextSpring,其中包含以下内容

public class SpringAnnotationWebInitializer extends
        AbstractContextLoaderInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(ApplicationContextSpring.class);
        return applicationContext;
    }

}

ApplicationContextSpring 将是

@Configuration
@ImportResource("classpath:applicationContext.xml")
@Import(SecurityConfig.class)
public class ApplicationContextSpring {

}

就像我说的,你最好创建 java 或 xml 配置。

【讨论】:

  • 我尝试了这样的解决方案,但再次出现此错误No bean named 'springSecurityFilterChain' is defined
  • 完全改变了我上面的答案。请立即通过它
  • 谢谢,我同意,我会尝试创建 .xml 配置
  • 对不起)我再次尝试了您的第一个变体,仅将此 &lt;filter&gt; &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy &lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; 添加到 web.xml 并且它正在工作,您可以将您的问题编辑为第一个变体,我将其标记为 true,谢谢)
【解决方案2】:

您正在 XML 配置中创建一个带有 null 过滤器列表的 FilterChainProxy bean,并且该 bean 被 DelegatingFilterProxy 在 web.xml 中使用。 FilterChainProxy#getFilters 尝试遍历 null 列表,自然会以 NullPointerException 失败。

问题的根源在于,你不能像这样混合 Java 配置和传统的 XML 配置。 Java 配置创建了一个单独的 FilterChainProxy bean,它与通过 XML 配置的 bean 无关。

【讨论】:

    猜你喜欢
    • 2013-04-19
    • 2019-06-28
    • 2015-04-12
    • 2011-07-02
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    相关资源
    最近更新 更多